Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多线程和锁_Java_Multithreading - Fatal编程技术网

Java 多线程和锁

Java 多线程和锁,java,multithreading,Java,Multithreading,在讨论条件之前,我试图了解锁和多线程是如何工作的。这是我目前正在测试的代码: public class tester { private static int count = 0; public void incrementCount() { count++; } public int getCount() { return count; } public static void main(String[] a

在讨论条件之前,我试图了解锁和多线程是如何工作的。这是我目前正在测试的代码:

public class tester {
    private static int count = 0;

    public void incrementCount() {
        count++;
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(new testing());
        Thread thread2 = new Thread(new testing());
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println(count);
    }
}
这是实现Runnable的部分:

public class testing implements Runnable {
    Lock lock = new ReentrantLock();
    tester in = new tester();

    public void run() {
        for (int i = 0; i < 1000; i++) {
            lock.lock();
            in.incrementCount();
            lock.unlock();

        }
    }
}

公共类测试实现可运行{
Lock Lock=新的可重入锁();
测试仪输入=新测试仪();
公开募捐{
对于(int i=0;i<1000;i++){
lock.lock();
in.incrementCount();
lock.unlock();
}
}
}
我遇到的问题是,我试图在主方法的末尾打印出2000个,但它实际上从未达到2000个,即使我使用锁。谢谢你的帮助

即使我用的是锁

您正在为两个线程中的每一个使用单独的锁

如果希望锁在线程之间协调,则它们都需要使用同一个锁实例。否则就毫无意义了

换成

class Testing implements Runnable {
    private final Lock lock;

    // pass in the lock to use via the constructor
    // both threads need to receive the same lock
    Testing(Lock lock){ this.lock = lock; }           

    public void run() {
        for (int i = 0; i < 1000; i++) {
            lock.lock();
            Tester.incrementCount();
            lock.unlock();
        }
    }
}
类测试实现可运行{
私人最终锁;
//通过构造函数传入要使用的锁
//两个线程都需要接收相同的锁
正在测试(锁){this.Lock=Lock;}
公开募捐{
对于(int i=0;i<1000;i++){
lock.lock();
Tester.incrementCount();
lock.unlock();
}
}
}

Thilo是正确的,但我认为可以用另一种方式来解释

锁(包括
Lock
实现和基本锁)的主要目的是获得对某些数据的独占访问。“议定书”是:

  • 获取锁
  • 访问和/或修改数据
  • 松开锁
假设当一个线程持有锁时,没有其他线程可以访问data1

但这只有在锁和数据之间存在一对一的关联时才有效。也就是说,为了获得独占访问权,您需要获得数据的锁。如果您获取了另一组数据的锁,它将不起作用。如果您试图对同一组数据使用多个锁,那么通常情况下2也不会起作用

在您的示例中,每个线程都有自己的锁,但只有一个数据是它们试图控制访问的。因此,两个线程可以同时访问和更新数据


蒂洛的回答说明了解决问题的正确方法


1-这实际上是线程之间的“契约”。Java语言不会(也不能)阻止线程在不持有锁的情况下访问和更新“受控”数据。线程必须遵守契约以实现适当的同步和互斥


2-通常,但不总是。例如,
ReadWriteLock
提供了一对锁对象,它们一起提供独占的读写访问或共享的只读访问。

我最终为两个线程使用了相同的测试实例,这样也可以吗?这在您的情况下也可以工作(因为
测试
实例中没有可变状态),但这非常令人困惑。不要给两个不同的线程提供相同的可运行实例。另外,由于
count
static
,因此根本不需要创建
Tester
的实例。