考虑以下代码:(注意:为了清楚起见,删除了所有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
循环?我知道是这样,因为
list1
和list2
都在结尾处都有2000个Integers
,这意味着两个线程都成功地完成了for
循环,每个循环process()
1000次,并分别调用了这两种方法时间。我唯一的猜测是,当线程遇到被锁定的同步块时,它将该块存储在队列(或其堆栈?)中并继续前进,直到该块再次释放。
最佳答案
据我了解,thread2
然后将跳过同步锁,退出methodA()和start methodB
不,thread2
将阻止,即。停止执行,直到另一个线程完成了methodA
并释放了锁。然后它将恢复执行,获取锁并执行该方法。
关于java - 线程如何知道如何“返回”先前锁定的块?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26344617/