Java对象锁定:调用其他方法时死锁?

时间:2012-06-25 17:12:42

标签: java multithreading locking deadlock

如果我在两个方法中使用synchronize(this)而另一个调用另一个方法,那么我是否会陷入死锁状态,或者它是否会起作用,因为线程已经拥有锁?

想象下面的课程:

public class Test {
  public void foo() {
    synchronize(this) {
      bar();
    }
  }

  public void bar() {
    synchronize(this) {
      // do something
    }
  }
}

如您所见,foo和bar有两种方法,它们都依赖于同步。

当调用foo()时,将获得一个锁(this);当foo调用时会尝试执行相同的操作(从而导致死锁)或者它是否会意识到锁已经被同一个线程获得了?

希望我的解释或多或少清楚; - )

3 个答案:

答案 0 :(得分:10)

synchronized块是可重入的(事实上,Java监视器是可重入的,非常清楚),因此在您的情况下不会发生死锁。

根据the docs

  

回想一下,线程无法获取另一个线程拥有的锁。   但是一个线程可以获得它已经拥有的锁。

答案 1 :(得分:3)

如果线程持有对象的锁定,它可以根据该锁定对象进入其他同步块。

Here你可以阅读

“... thread 可以获取它已经拥有的锁。允许线程多次获取同一个锁启用可重入同步。这描述了一种情况同步代码直接或间接地调用也包含同步代码的方法,并且两组代码使用相同的锁。如果没有重入同步,同步代码必须采取许多额外的预防措施以避免线程导致自身阻塞。 “

答案 2 :(得分:0)

要注意的一件事是:

Thread A has the lock in foo() and needs to call bar()

and Thread B has the lock in bar() while needing to call foo()