【问题标题】:Java: Nested synchronization blocksJava:嵌套同步块
【发布时间】:2012-05-09 01:23:01
【问题描述】:

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

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

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

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

【问题讨论】:

  • 在这种情况下,所有线程都会被外锁阻塞,直到被内锁线程释放。
  • 您发布的代码片段没有任何作用;唯一可以拥有lock2 的线程是拥有lock1 的线程。在不知道其余代码是什么以及这些锁的用途是什么的情况下,无法回答。
  • 你在看哪篇文章?

标签: java multithreading concurrency


【解决方案1】:

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

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

  2. 1234563

【讨论】:

  • 请问是否有解决嵌套监视器锁定的方法?是否可以在内锁和外锁上都调用等待或者没有办法做到这一点?
  • 死锁需要 4 个先决条件。互斥(所以 sync(nodes) { sync(edges) { } } 而另一个函数有 sync(edges) { sync (nodes) { } } ),非抢占性,循环等待和资源持有。只有互斥是不够的,才会出现死锁。如果您好奇,这些被称为科夫曼条件。 en.wikipedia.org/wiki/Deadlock_prevention_algorithms
【解决方案2】:

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

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

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

现在如果有多个线程尝试访问这些方法,则可能会因为嵌套的同步块而出现死锁。

【讨论】:

    【解决方案3】:

    根据Nested Monitor Lockout Tutorial

    在嵌套监视器锁定中​​,线程 1 持有锁 A,并等待 来自线程 2 的信号。线程 2 需要锁 A 来发送 向线程 1 发出信号。当处于死锁状态时,两个线程正在等待对方释放锁。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-01
      • 2011-12-11
      • 1970-01-01
      相关资源
      最近更新 更多