线程如何知道如何"返回"先前锁定的块?

Tib*_*riu 0 java multithreading synchronization

考虑以下代码:(注意:为了代码清晰,删除了所有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));
    }
}
Run Code Online (Sandbox Code Playgroud)

现在假设创建了2个线程,并且两个线程都只是调用process()它们的方法run().

假设当thread2尝试访问时,thread1 methodA()已经锁定了.根据我的理解,thread2将跳过同步锁定,退出methodA()和启动methodB(这是拥有多个锁定对象的点).但我的问题是thread2如何知道"重新启动"并完成methodA(),而不仅仅是继续for循环?

我知道这个情况是因为list1list2都有2000 Integers在它们的尽头,这意味着两个线程成功完成了for循环中process()每1000次,每一次所谓的两种方法.

我唯一的猜测是,当一个线程遇到一个被锁定的同步块时,它会将该块存储在队列(或其堆栈?)中并继续运行,直到该块再次空闲.

Sot*_*lis 6

根据我的理解,thread2然后跳过同步锁,退出methodA(),然后启动methodB

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