考虑以下代码:(注意:为了代码清晰,删除了所有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));
}
}
现在假设创建了两个线程,并且只是在process()
中调用run()
方法。
假设当thread2尝试访问methodA()
时,thread1已经锁定了。根据我的理解,thread2将跳过同步锁定,退出methodA()
,然后启动methodB
(这是拥有多个锁定对象的点)。但我的问题是如何将thread2知道&#34;返回&#34;并完成methodA()
,而不只是继续for
循环?
我知道情况就是这样,因为list1
和list2
最后都有2000 Integers
,这意味着两个线程都成功完成了for
循环{ {1}}每次1000次,每次都调用两种方法。
我唯一的猜测是,当线程遇到被锁定的同步块时,它会将该块存储在队列(或其堆栈?)中并继续运行,直到该块再次空闲。
答案 0 :(得分:6)
根据我的理解,
thread2
将跳过同步锁定,退出methodA(),然后启动methodB
不,thread2
会阻止,即。停止执行,直到另一个线程完成methodA
并释放锁定。然后它将恢复执行,获取锁定并执行该方法。
答案 1 :(得分:0)
方法()和方法()被顺序调用,所以如果在methodA()中存在锁定,除非锁定被清除,否则线程将处于阻塞状态。