如果一个方法是同步的,被调用的方法是否也必须同步?

If a method is synchronized, do the called methods also have to be synchronized?

如果一个方法是同步的,被调用的方法是否也必须同步?以下示例中正确的是什么?

// Only parent method synchronized 
public synchronized void parentMethod() {
    childMethod1();
}

public void childMethod1() {
    childMethod2();
}

public void childMethod2() {
    
}



// All methods synchronized 
public synchronized void parentMethod() {
    childMethod1();
}

public synchronized void childMethod1() {
    childMethod2();
}

public synchronized void childMethod2() {
    
}

If a method is synchronized, do the called methods also have to be synchronized?

没有

没有一般理由需要从另一个 synchronized 方法调用 synchronized 方法。

假设这些方法在同一对象上同步,那么所有模式都是有效的,具体取决于您要实现的目标:

  • synchronized 方法调用 synchronized 方法
  • 从普通方法调用 synchronized 方法
  • synchronized 方法调用普通方法
  • 从普通方法调用普通方法

在除最后一种情况之外的所有情况下,被调用的方法都将锁定目标对象。

(在第一种情况下,看起来好像线程两次访问同一个对象。事实上,Java 原始锁是可重入的……所以这不是问题。)


如果方法调用在不同的 目标对象上,它会变得有点复杂。现在您必须考虑您的应用程序是否需要锁定这两个对象。您还需要考虑死锁的可能性。 (如果两个线程试图同时获取相同的两个原始锁,但顺序不同,就会出现死锁。)


关于哪些方法需要同步1,实际上不可能给出硬性规定。这取决于方法的作用,以及您是否使用原始锁互斥锁或其他一些机制(Lockvolatile、不可变类型等)来同步 and/or 确保内存可见性。即使对于原始锁互斥锁,您也可以使用 synchronized 块的 synchronized 方法来实现相同的目的。


1 - 请注意,这个问题无论如何都不会问这个问题!