7

私は最近、 Crack Code Interviewという本を読んでいますが、257 ページに非常に混乱する段落があります。

スレッドは、プロセスの特定の実行パスです。1 つのスレッドがプロセス リソースを変更すると、変更はすぐに兄弟スレッドに表示されます。

IIRC では、1 つのスレッドが変数に変更を加えた場合、その変更は最初に CPU キャッシュ (L1 キャッシュなど) に保存され、変数が volatile として宣言されていない限り、他のスレッドとの同期は保証されません。

私は正しいですか?

4

2 に答える 2

10

いいえ、あなたは間違っています。しかし、これは非常によくある誤解です。

最新のマルチコア CPU はすべて、ハードウェアキャッシュ コヒーレンスを備えています。L1 および同様のキャッシュは表示されません。L1 キャッシュのような CPU キャッシュは、メモリの可視性とは何の関係もありません。

スレッドがプロセス リソースを変更すると、変更はすぐに表示されます。問題は、プロセス リソースがコードで指定された順序どおりに変更されない原因となる最適化です。

コードにk = j; i = 4; if (j == 2) foo();オプティマイザがある場合、最初の代入で の値が読み取られることがありjます。2そのため、変更されていないことを「認識」しているため、比較するときに再度読み取る必要がない場合があります。ただし、別のスレッドによって変更された可能性があります。したがって、スレッド間の同期が必要な場合は、ある種の最適化を無効にする必要があります。それがそのようなvolatileことです。

コンパイラと CPU が最適化を行わず、書かれたとおりにプログラムを正確に実行した場合、volatile必要になることはありません。メモリの可視性は、キャッシュではなく、コードの最適化に関するものです (一部はコンパイラによって行われ、一部は CPU によって行われます)。

于 2013-04-28T05:04:39.393 に答える
2

あなたが引用している文章は間違っていると思います。Java メモリ モデルの全体的な考え方は、最新のソフトウェアとハ​​ードウェアによる複雑な最適化に対処することです。これにより、プログラマは、他のスレッドのそれぞれの読み取りによってどの書き込みが表示されるかを判断できます。

Java のプログラムが適切に同期されていない限り、1 つのスレッドによる変更がすぐに他のスレッドに表示されることを保証することはできません。おそらく、テキストは非常に具体的な (そして弱い) メモリ モデルを参照しています。

volatile 変数の使用は、スレッドを同期する 1 つの方法にすぎず、すべてのシナリオに適しているわけではありません。

- 編集 -

私は今、混乱を理解していると思います...次のことを前提として、David Schwartzに同意します:

1)「プロセスリソースを変更する」とは、高水準のコンピューター言語で書かれた書き込み命令の実行だけでなく、リソースの実際の変更を意味します。

2) 「兄弟スレッドにすぐに見える」とは、他のスレッドがそれを見ることができることを意味します。プログラム内のスレッドが必ずしもそれを見るという意味ではありません。リソースへの実際のアクセスをバイパスする最適化を無効にするために、同期ツールを使用する必要がある場合があります。

于 2013-04-28T05:11:23.593 に答える