Java:嵌套同步块

我在Heinz Kabutz的Java专家通讯版本中看到了这一点,虽然Kabutz博士的文章的其余部分(实际上是全部)都得到了很好的解释和详细说明,但他似乎很清楚这段代码的作用,或者更重要的是,它的意义是:

public class SomeObject { private Object lock1; private Object lock2; public void doSomething() { synchronized(lock1) { synchronized(lock2) { // ... } } } } 

嵌套synchronized块的含义是什么? 这如何影响尝试doSomething()不同线程?

有两个可能需要注意的问题

  1. 如果使用wait / notify,嵌套锁可能很容易导致死锁。 这是对原因的解释。 http://tutorials.jenkov.com/java-concurrency/nested-monitor-lockout.html

  2. 一个人应该警惕,如果另一个方法希望锁定相同的两个对象,它们必须始终以相同的顺序执行,否则可能会出现另一种死锁情况,如本文所述: 如何避免嵌套同步和导致的死锁

这个代码片段本身不会引起任何问题。 但是如果有类似这样的代码,问题可能会以死锁的forms出现; 我们有两个方法使用同步块,使对象以相反的顺序锁定 –

 public void doSomething() { synchronized(lock1) { synchronized(lock2) { // ... } } } public void doOtherthing() { synchronized(lock2) { synchronized(lock1) { // ... } } } 

现在,如果多个线程试图访问这些方法,那么由于嵌套的同步块可能会出现死锁。

根据嵌套监视器锁定教程

在嵌套的监视器锁定中​​,线程1持有锁A,并等待来自线程2的信号。线程2需要锁A将信号发送到线程1.在死锁时,两个线程正在等待彼此释放锁。

死锁可能类似于两个人被关在两个房间里,他们想转换到另一个房间,但他们都只有对方的钥匙。 虽然嵌套的监视器锁定就像老板一样安排在一个房间里睡觉,并且假设只有当有人进入房间时他才会被唤醒。 秘书负责唤醒他的老板。 但老板在睡觉的时候仍然拿着房间的钥匙,所以秘书不能进来唤醒他。