同步方法以递归方式调用自身。这是坏的吗?

2022-09-01 10:12:57

这个问题的要点是说明Java没有像我预期的那样工作。

您希望以下代码的行为方式如何?

public class SynchTester {
  private static SynchTester synchTester;

  public synchronized static SynchTester getSynchTester(){
    if(synchTester==null){
      synchTester = new SynchTester();
    }

    return synchTester;
  }

  private SynchTester() {
    SynchTester myTester = getSynchTester();
  }

  public static void main(String[] args) {
    SynchTester tester = SynchTester.getSynchTester();
  }
}

我希望它挂在死锁上等待递归完成,但它会抛出StackOverflow。显然,同步不会阻止对同一线程的访问。

这是一个错误吗?


答案 1

在 Java 中,同步锁是可重入的

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

来源:见本页底部


答案 2

同步方法需要能够在监视器对象上获取锁。监视器对象是实例(或静态方法的类)。已经具有锁的线程不需要再次获取它。所以,是的,这可能会导致堆栈溢出(harhar)。


推荐