10

変数をvolatileJavaのようにマークすると、すべてのスレッドに、古い値ではなく、最後に書き込まれた値が表示されます。これが実際にどのように達成されるのか疑問に思いました。JVMは、CPUキャッシュなどをフラッシュする特別な命令を発行しますか?

4

2 に答える 2

10

私が理解していることから、それは常に書き込み後にキャッシュがフラッシュされたかのように見え、読み取り時にメモリから直接行われたように見えます。その結果、スレッドは常に別のスレッドからの書き込みの結果を確認し、(Javaメモリモデルによると)キャッシュされた値を確認することはありません。ただし、実際の実装とCPU命令は、アーキテクチャごとに異なります。

明らかに実際の同期がないため、複数のスレッドで変数をインクリメントしたり、その値を確認して何らかのアクションを実行したりしても、正確性は保証されません。通常、変数へのスレッド書き込みのみがあり、他のスレッドがすべて読み取りを行っている場合にのみ、正しい実行を保証できます。

また、64ビットの非揮発性変数は2つの32ビット変数として読み取り/書き込みできるため、32ビット変数は書き込み時にアトミックですが、64ビット変数はそうではないことに注意してください。半分は別の半分の前に書き込むことができるため、読み取られる値は古い値でも新しい値でもかまいません。

これは私のブックマークからの非常に役立つページです:

http://www.cs.umd.edu/~pugh/java/memoryModel/

于 2010-04-22T21:05:17.503 に答える
1

正確に何が起こるかはプロセッサ固有です。一般に、何らかの形式のメモリバリア命令があります。キャッシュ全体をフラッシュすることは明らかに非常にコストがかかります-ハードウェアにはキャッシュコヒーレンシプロトコルがあります。

また重要なのは、フィールドアクセス全体で特定の最適化が行われないことです。マルチスレッドを検討する場合、コンパイラは重要です。ハードウェアについて考えるだけではありません。

于 2010-04-22T21:05:16.070 に答える