この質問のポイントは、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をスローします。明らかに同期されても、同じスレッドへのアクセスはブロックされません。
これはバグですか?
同期されたメソッドは、モニターオブジェクトのロックを取得できる必要があります。モニターオブジェクトはインスタンス(または静的メソッドのクラス)です。すでにロックされているスレッドは、再度ロックを取得する必要はありません。そうです、それはスタックオーバーフロー(harhar)を引き起こす可能性があります。
Javaチュートリアル から:
1つのスレッドがオブジェクトの同期メソッドを実行している場合、同じオブジェクトブロックの同期メソッドを呼び出す他のすべてのスレッドは、最初のスレッドがオブジェクトで完了するまで実行を一時停止します。
したがって、syncronizedキーワードは期待どおりに機能し、同期された再帰呼び出しはJavaでは完全に合法(および機能)であると思います。