「こんにちは、アミーゴ!」

「Java メモリ モデルという大きなトピックがあります。基本的に、それについてまだ知る必要はありませんが、聞いておくと役に立つでしょう。」

「潜在的な問題をすべて排除するために、Java はメモリ管理メカニズムを変更しました。現在では、メモリは単にスレッドのローカル キャッシュとグローバル メモリに分割されるだけではなく、メカニズムはさらに優れています。」

「そしてさらに複雑です!」

「はい、より良く、より複雑です。それは飛行機のようなものです。飛行機で飛ぶことは歩くよりも良いですが、より複雑です。新しい状況を非常に簡単に説明しようとします。」

「これが彼らが考え出したものです。「happens-before」と呼ばれるローカル スレッド メモリを同期するメカニズムがコードに追加されました。いくつかのルール/条件が考案されました。これらの条件が満たされると、メモリは同期されるか、現在のメモリに更新されます。州。

「ここに例があります:」

注文 スレッド 1 スレッド 2
1
2

101
102
103
104
105

201
202
203
204
205
public int y = 1;
public int x = 1;

x = 2;
synchronized(mutex)
{
 y = 2;
}
スレッドはミューテックスが解放されるのを待っています

synchronized(mutex)
{
 if (y == x)
 System.out.println("YES");
}

「これらの条件の 1 つは、解放されたミューテックスの取得です。ミューテックスが解放されて再取得される場合、メモリは取得前に同期されます。スレッド 2 は、変数 x と y の「最新」の値を参照します。それらを揮発性であるとは宣言しません。」

「なんと興味深いことでしょう!そして、このような条件はたくさんあるのでしょうか?」

「もう十分です。メモリを同期するための条件は次のとおりです。」

  • 「単一スレッド内では、すべてのコマンドは、ソース コード内でそれに続くすべての操作の前に発生します。」
  • 「ロックの解放は、同じロックが取得される前に発生します。」
  • 同期されたブロック/メソッド からの終了は、同期されたブロック/メソッドが同じモニターに入る前に発生します。」
  • 「揮発性フィールドのメモリへの書き込みは、同じ揮発性フィールドがメモリから読み取られる前に行われます。」
  • 「Thread オブジェクトの run メソッドの終了は join() メソッドが終了する前、または同じスレッド内のオブジェクトに対して isAlive() メソッドが false を返す前に発生します。」
  • 「Thread オブジェクトの start() メソッドの呼び出しは、同じスレッド内のオブジェクトで run() メソッドが開始される前に行われます。」
  • 「コンストラクターの終了は、このクラスの Finalize() メソッドの開始前に発生します。」
  • 「interruptedException がスローされたため、または isInterrupted() メソッドまたはinterrupted() メソッドを使用したため、スレッドがこのメソッドが呼び出されたことを判断する前に、interrupt() メソッドの呼び出しが発生します。

「それで、思ったよりも少し複雑ですか?」

「はい、もう少し複雑です…」

「ありがとう、リシ。考えてみます。」

「この話はあまり気にしないでください。いずれ自分で理解できる時が来ます。今は深い森を深く理解するよりも、基礎を理解した方が良いでしょう」 Java マシンの内部動作。Java 9 がリリースされ、その後すべてが再び変わります。」

「O_o。そうですね…知らない方が良いこともあります。」