嵌套的synchronized关键字

时间:2011-02-03 08:15:09

标签: java synchronization

我在Java中有这个代码:

    public void doSomeThing() {
        synchronized (this) {
            doSomeThingElse();
        }
    }
    public void doSomeThingElse() {
        synchronized (this) {
            // do something else
        }
    }

此代码可以阻止吗?我的意思是,这段代码可以等待吗?

6 个答案:

答案 0 :(得分:49)

作为可重入锁定的java documentation describes

  

线程可以获取它的锁   已经拥有

第二个同步块使用相同的锁,因此总是可以使用,因为已经在外部方法中获取了锁。

不,不会出现僵局。

答案 1 :(得分:8)

如果一个帖子拥有this上的锁,它会进入其他synchronized方法/块,就像黄油中的热刀一样。

答案 2 :(得分:3)

在同步块中,您可以重新获取已拥有的锁。第一个线程将获取锁定提供程序(this)以输入doSomething()。然后在doSomethingElse()方法中,它将重新获取它。

这样做的原因?好吧没有什么可说的,没有其他线程从其他地方输入doSomethingElse。这将阻止任何代码在doSomething()中执行块,直到doSomethingElse()中的线程释放“this”。

编辑 BTW它当然可以阻止...它会阻止任何不拥有同步对象的线程执行。但是它不会(如已发布)死锁。

答案 3 :(得分:1)

Lock已经被执行doSomething方法的线程所取代,因此该线程可以执行doSomethingElse方法。

您需要两个锁定对象来创建死锁情况。在您的情况下,只有一个,因此不可能创建死锁。

答案 4 :(得分:0)

this两种情况下的同步使用,因此如果运行doSomeThing中的synchronized块,则您已经拥有了锁,因此您可以执行doSomeThingElse方法。

如果您的代码非常简单,则相当于:

public synchronized void doSomeThing() {
    doSomeThingElse();
}
public synchronized void doSomeThingElse() {
    // do something else
}

答案 5 :(得分:0)

您已经在第一次同步中取得了监视器锁定。 您应始终确保并发设计不会对性能产生巨大影响。

确保这一点的一种方法是仅同步所需的语句/代码。

现在假设您的代码看起来像这样。

public void doSomeThing()
 {
  synchronized (this) 
   {             
    synchronized (this) 
     {             
      // do something else         
     }           
   }     
 }

这是必需的

public void doSomeThing()
     {
       doSomeThingElse();     
     }
public void doSomeThingElse()
{
 synchronized (this) 
         {             
          // do something else         
         }
}