メソッド全体を同期することにした場合、次のようにデッドロックが発生する可能性があります。 methodA1 のメソッド呼び出しの場合、クラス A はそのオブジェクトのロックを取得し、次にクラス B オブジェクトの methodB2() を呼び出すことを決定し、ClassB のロックを取得しようとします。 . ただし、ClassB のオブジェクトでメソッド呼び出し methodB1() が進行中の場合、ClassA が B のロックを取得しようとする試みと、同様に ClassB が ClassA のロックを取得しようとする試みは失敗し、デッドロックが発生します。
class ClassA {
public synchronized void methodA1(ClassB classB) {
classB.methodB2();
}
public synchronized void methodA2() { }
}
class ClassB {
public synchronized void methodB1(ClassA classA) {
classA.methodA2();
}
public synchronized void methodB2() { }
}
連携するオブジェクト間でデッドロックが発生するのを防ぐために、非公開の final Lock オブジェクトを使用することをお勧めします。
private final Object lock = new Object();
void addUser(String userName) {
synchronized(lock){
// method body. Add user to list
} // lock is released. now any cooperating object can use 'lock'.
// addUser can obtain a lock on any cooperating object.
}