私は、Javaのメモリモデルについては、この理論的な質問があります。私は、次のクラスでは、これらの2つの要求ハンドラを持つサーバーがあるとします。
class MyHandlers {
volatile int someFlag = 0;
String handleFirstRequest() {
someFlag = 1;
return "Hello!";
}
String handleSecondRequest() {
return "value of someFlag: " + someFlag;
}
}
私はまた、クライアントを持っています。私のクライアントは、トリガーがhandleFirstRequestを実行するネットワーク要求を送信します。クライアントは、要求が完了するまで待機します。最初の要求が完了すると、クライアントはhandleSecondRequestをトリガーする第2の要求を送信します。
質問:どのようにJavaのメモリモデルがあることから、第2の要求に対する応答を防止しませんか"value of someFlag: 0"
?
注:私は実際には、第二の応答を処理するスレッドが常に表示される、ということを理解someFlag
1として。
私が正しくJMMを読めば、揮発性の読み取りおよび揮発書き込み(注文しまうトータルため、ある同期順序がありsomeFlag = 1
、私の例では)。読み取り、書き込みの後にある場合は、読み取りは書き込みが表示されます。それは、書き込みが読み取りに続くケースを持っていることは可能ですか?この場合、書き込みを読むと、同期していない、と何が起こる-前の書き込みと読み取りの間の関係はないだろう。これは見るために第2の要求を処理するスレッドを招くsomeFlag
私の理解行く間違ってい0として?
追加の思考(2020年3月2日): JMMは、時間の概念を指すものではありません。同期アクションは、同期順序に従って順序付けされていますが、JMMには何も同期順序は、アクションの順序は、時間によってソートされたものと同じであることを述べていません。これは、Javaの実装はの読み取りを命ずることができる提案するsomeFlag
前に、読み込みが発生していても、書き込み後にクロックに係る書き込み。JMMのみことを保証ように思える場合は揮発性の読み取りが揮発書き込み後に発注される揮発性書き込みがに見える前に、その後、揮発性のリード後に読み込み書き込みます。
私は私の答えを見つけました!
Java言語仕様のセクション17.4.3は、次のように述べています:
シーケンシャル一貫性は、プログラムの実行中に可視性と順序について行われている非常に強力な保証です。順次一貫実行内で、そこプログラムの順序と一致している(例えば、読み出し、書き込みなど)は、すべての個々のアクションを完全に順序があり、そして個々の各アクションは原子されており、すべてのスレッドに直ちに可視。
Javaのメモリモデルでは、「アクションは」揮発性書き込みを含め、スレッド間の操作を参照してください。この段落の保証はJLSに準拠しては、揮発性の書き込みが他のスレッドにすぐに表示されることを保証する任意のJava実装という。オープニングポストの例では、この段落は、揮発性の読み取りが揮発書き込み前に注文することができないことを保証します。