25

我在 Heinz Kabutz 的Java 专家时事通讯版本之一中看到了这一点,尽管 Kabutz 博士的其余(实际上是所有)文章解释得很好且详细,但他似乎掩盖了这段代码的作用,或者更重要的是,它的意义在于:

public class SomeObject {
    private Object lock1;
    private Object lock2;

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

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

4

3 回答 3

35

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

  1. 如果使用等待/通知,嵌套锁很容易导致死锁。以下是原因的解释。http://tutorials.jenkov.com/java-concurrency/nested-monitor-lockout.html

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

于 2012-04-28T16:10:53.377 回答
3

就其本身而言,此代码段不会引起任何问题。但是如果有这样的代码,问题可能会以死锁的形式出现;我们有两种同步块的方法,以相反的顺序锁定对象-

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

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

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

于 2015-08-07T17:55:10.247 回答
0

根据嵌套监视器锁定教程

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

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

于 2016-12-30T09:39:30.607 回答