6

コードのどこかに空のsynchronizedブロックを書いたとします。

synchronized(obj){
   //No code here
}

同期されたブロックにはコードが含まれていないため、JIT コンパイラはobjそれをロックしないことで最適化しますか?

Java コンパイラはロックの粗化などの同様のトリックを行いますが、この同期ブロックも最適化されますか?

編集:

assylias の指摘によると、

synchronized(new Object()){
   //empty block
}

メソッドをエスケープしないオブジェクトを使用しているため、JIT コンパイラはこれを最適化できるようになりますか?

4

1 に答える 1

15

これは、Java メモリ モデルのセマンティクスに基づいて最適化することはできません。ロックの取得と解放の操作別のものに置き換えることができますが、空のsynchronizedブロックであっても、同じロックを取得している他のスレッドが実行するアクションの可視性に影響を与えます。

具体的には、ロックを解放する前に 1 つのスレッドによって実行されたすべての書き込みアクションが、同じロックを取得した後、他のスレッドから見えるという保証があります。

あなたの編集について

これは非常に異なるケースです。エスケープ分析によって、他のスレッドがそれを取得できないことが証明できるオブジェクトでロックが取得されます。synchronizedこの場合、ブロックの内容が何であるかは問題ではありません。ポイントは、使用されるロックのみです。コードは、投稿したとおりに表示することも、次のように表示することもできます。

Object o = new Object();
synchronized(o) { 
   // any operations you like, as long as they don't let o escape the method scope
}

これは、 lock elisionと呼ばれる変換によって実行できます。JVM は、synchronizedブロックをまったく見なかったふりをすることができます。これは、JMM セマンティクスが 1 つの同じロックを取得する場合のみを参照しているためです。

于 2013-08-05T10:41:10.597 に答える