synchronized
Java でキーワードを使用する場合、どの同期プリミティブが正確に使用されますか? Lock, Semaphore, Monitor, Mutex
?
編集: JVM はどのようにネイティブ レベルでロックを実装しますか?
synchronized
Java でキーワードを使用する場合、どの同期プリミティブが正確に使用されますか? Lock, Semaphore, Monitor, Mutex
?
編集: JVM はどのようにネイティブ レベルでロックを実装しますか?
バイトコード レベルでは、java には操作がmonitorenter
あり、 Java 仮想マシン仕様のこのページに記載されています。以下にスニペットを貼り付けます ( objectrefは操作のオペランドで、スタックから取得されます)。monitorexit
各オブジェクトには、それに関連付けられたモニターがあります。monitorenterを実行するスレッドは 、 objectrefに関連付けられたモニターの所有権を取得します。別のスレッドがobjectrefに関連付けられたモニターを既に所有している場合、現在のスレッドはオブジェクトがロック解除されるまで待機し、所有権の取得を再試行します。現在のスレッドがobjectrefに関連付けられたモニターを既に所有している場合、このスレッドがモニターに入った回数を示すモニターのカウンターをインクリメントします。objectrefに関連付けられたモニターがどのスレッドにも所有されていない場合、現在のスレッドがモニターの所有者になり、このモニターのエントリ数が 1 に設定されます。
現在のスレッドは、 objectrefによって参照されるインスタンスに関連付けられたモニターの所有者である必要があります。スレッドは、このモニターに入った回数を示すカウンターをデクリメントします。その結果、カウンターの値がゼロになった場合、現在のスレッドはモニターを解放します。objectrefに関連付けられたモニター が解放されると、そのモニターの獲得を待機している他のスレッドは解放を試みることができます。
したがって、「モニター」が答えであり、これも、NPEの答えで参照されているJLSも、ネイティブコードレベルで何が起こるかを指定していません。特定のプラットフォーム (CPU とオペレーティング システム) と特定の JVM 実装 (バージョンを含む) を念頭に置いている場合は、もちろん、JVM ソース (オープン ソース JVM の場合) を見るか、ここで質問することができます。
私は 1997 年のこのブログにも出くわしました。詳細が記載されています。
JLS から ( §17.1. 同期):
Java プログラミング言語は、スレッド間で通信するための複数のメカニズムを提供します。これらの方法の最も基本的なものは同期であり、モニターを使用して実装されます。Java の各オブジェクトは、スレッドがロックまたはロック解除できるモニターに関連付けられています。一度に 1 つのスレッドだけがモニターのロックを保持できます。そのモニターをロックしようとする他のスレッドは、そのモニターのロックを取得できるまでブロックされます。スレッド t は、特定のモニターを複数回ロックする場合があります。ロックを解除するたびに、1 回のロック操作の効果が逆になります。
したがって、「モニター」が最初の質問に対する答えです。
2 番目の質問に関しては、これは特定されていない実装の詳細です。