4

如果我在两种方法中使用 synchronize(this) 并且一种调用另一种方法,我会陷入死锁情况还是会因为线程已经拥有锁而工作?

想象一下下面的班级:

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

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

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

调用 foo() 时,会在 (this) 上获得一个锁;bar 会在 foo 调用时尝试做同样的事情(从而导致死锁)还是会意识到锁已经被同一个线程获得?

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

4

3 回答 3

10

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

根据文档

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

于 2012-06-25T17:13:31.807 回答
3

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

在这里你可以读到

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

于 2012-06-25T17:14:58.370 回答
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()
于 2012-06-25T17:22:49.797 回答