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



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

想象一下下面的类:

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

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

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

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

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

根据文档:

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

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

在这里你可以读到的

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

需要注意的一件事是:

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()

最新更新