考虑以下代码:(注意:为了清楚起见,删除了所有try / catch)

Object lock1 = new Object();
Object lock2 = new Object();
List<Integer> list1 = new ArrayList<Integer>();
List<Integer> list2 = new ArrayList<Integer>();

public void process() {
    for (int i = 0; i < 1000; i++) {
        methodA();
        methodB();
    }
}

public void methodA() {

    synchronized (lock1) {
        Thread.sleep(1); // mimics other operations
        list1.add(random.nextInt(100));
    }
}

public void methodB() {

    synchronized (lock2) {
        Thread.sleep(1); // mimics other operations
        list2.add(random.nextInt(100));
    }
}


现在假设创建了2个线程,并且都在其process()中简单地调用了run()方法。

假设当线程2尝试访问methodA()时,线程1已经获取了锁定。据我了解,线程2然后将跳过同步锁,退出methodA(),然后启动methodB(这是拥有多个锁对象的关键)。但是我的问题是,然后thread2将如何知道“备份”并完成methodA(),而不是仅继续执行for循环?

我知道是这样,因为list1list2都在结尾处都有2000个Integers,这意味着两个线程都成功地完成了for循环,每个循环process() 1000次,并分别调用了这两种方法时间。

我唯一的猜测是,当线程遇到被锁定的同步块时,它将该块存储在队列(或其堆栈?)中并继续前进,直到该块再次释放。

最佳答案

据我了解,thread2然后将跳过同步锁,退出methodA()和start methodB


不,thread2将阻止,即。停止执行,直到另一个线程完成了methodA并释放了锁。然后它将恢复执行,获取锁并执行该方法。

关于java - 线程如何知道如何“返回”先前锁定的块?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26344617/

10-11 22:29
查看更多