3

Java メモリ モデルを理解するための助けが必要です。以下は、基本的な概念を理解するための一般的な例です。

Image というオブジェクト インスタンスとShared、2 つのスレッドAとがありBます。さらにQueue、同期puttake.

スレッドは、メソッドのおよびメソッド内で-instanceAを変更します。Sharedput

質問 1:からのすべての変更は、同期メソッドを介してオブジェクト インスタンスを取得するAときに表示されますか?BSharedtake

質問 2: メモリ キャッシュは、同期メソッドSharedを終了するとすぐにフラッシュされます (すべての変更が表示されます) 。が-method で によって呼び出された場合、正確にはどうなりますか? -methodをまだ終了していなくても、変更が行われたことがわかりますか? 呼び出し時にキャッシュもフラッシュされますか?Aputwait()putABSharedAsynchronizedwait()

4

3 に答える 3

4

回答 1 : はい。take() と put() の両方が同期されているためです。したがって、B が take() を実行する前に、A は同期ブロックを離れている必要があり、同期ブロックを離れることは、メモリ キャッシュ (メモリ フェンス/バリア) をフラッシュすることを意味します。

回答 2 : はい。なぜなら、wait() が呼び出されると、スレッドはロックを放棄する必要があり、これによって再びメモリ フラッシュが発生するからです。

編集:あなたが求めているのは、同期ブロックの終了時またはロックの解放時にキャッシュ書き込みが発生するかどうかということだと思います。答えは、 lock の解放時に cache-write-to-memory が発生することです。

于 2011-11-26T14:42:20.373 に答える
2

Aはまだ同期メソッドを終了していませんか?wait()を呼び出すときにキャッシュもフラッシュされますか?

JSR 133(Javaメモリモデル)FAQからの引用-同期は何をしますか?

同期ブロックを終了した後、モニターを解放します。これにより、キャッシュがメインメモリにフラッシュされ、このスレッドによって行われた書き込みが他のスレッドに表示されるようになります。同期ブロックに入る前に、モニターを取得します。これは、ローカルプロセッサのキャッシュを無効にして、変数がメインメモリから再ロードされるようにする効果があります。これで、以前のリリースで表示されたすべての書き込みを確認できるようになります。

これは、モニターが解放されたときにキャッシュをメモリにフラッシュすることを示しています。同期ブロックを終了するときにモニターが解放される一方で、waitメソッドを呼び出すときにもモニターが解放されることに注意してください。したがって、変更は#wait()呼び出しでフラッシュされ、同じモニターで以前に待機していた場合は、他のスレッドによって取得されると予想されます。

于 2011-11-26T15:01:11.883 に答える
2

最初の質問に対する答えは「はい」です。これは、同期ポイント (put と take に存在する) によって暗黙的なメモリ フェンスが導入されるためです。

2 番目の質問については、オブジェクトが に追加される前または後に A 呼び出しが待機するかどうかによって異なりますShared。以前の場合、明らかに共有に変更がないため、B には目新しいものは何もありません。

編集: A 呼び出しが後で待機する場合、追加する前にロックを取得し、待機中にロックを解放する必要があったため、変更が表示されます。これにより、フェンスも導入されます。

したがって、どちらの場合も答えはイエスです。

于 2011-11-26T14:40:37.643 に答える