考虑以下代码:(注意:为了代码清晰起见,删除了所有 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 个线程,并且都简单地在其 run()
中调用 process()
方法。
假设当线程 2 尝试访问 methodA()
时,锁已被线程 1 占用。据我了解,thread2 将跳过同步锁,退出 methodA() 并启动 methodB (这就是拥有超过 1 个锁对象的要点)。但我的问题是,thread2 如何知道“返回”并完成 methodA()
,而不是仅仅继续 for
循环?
我知道是这种情况,因为 list1
和 list2
末尾都有 2000 个 Integers
,这意味着两个线程都成功完成process()
中的 for
循环各 1000 次,并且每次都调用这两个方法。
我唯一的猜测是,当线程遇到锁定的同步块(synchronized block)时,它将将该 block 存储在队列(或其堆栈?)中并继续移动,直到该 block 再次空闲。
最佳答案
From what I understood,
thread2
will then skip the synchronized lock, exit methodA(), and start methodB
不,thread2
将阻塞,即。停止执行,直到另一个线程完成 methodA
并释放锁。然后它将恢复执行,获取锁并执行该方法。
关于java - 线程如何知道如何 "go back"到先前锁定的 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26344617/