次のコードを参照してください
Thread.sleep(1) を Thread.sleep(1000) に置き換えて、 flag の変更された値 ( td ) を取得します。 isFlag()はtrueを返します。 Java メモリ モデルの概念は読んだことがありますが、このコードをどう説明すればよいかわかりません。誰が説明できますか?
Thread.sleep(1)
Thread.sleep(1000)
flag
td ) を取得します。 isFlag()
true
関連する質問: Java マルチスレッドの作業メモリはどれくらいですか?
まず、期待される効果を教えてください。質問は明確にしましょう
この期待は標準ではサポートされていません。コード内では、「メインスレッドの読み取り前にサブスレッドの書き込みが発生する」ことを保証するための処理は何も行われていません。
sleep(1000)後で変更が表示されるのは単なる偶然です。JVM がメインスレッドに変更を表示するまで長時間待機する場合、またはメインスレッドに変更を表示させない場合でも、仕様には違反しません。
sleep(1000)
あなたのプログラムをテストする必要があります volatile 关键字的功能。但是 “把 Thread.sleep(1) 换成 Thread.sleep(1000) 就能获得预期效果” 这样做理解上是不对的。首先,程序中总共有两个线程,主线程(暂称 线程M)和 new Thread(td) (暫定的にスレッド T と呼ばれます)。
volatile
new Thread(td)
の値を書き込むとき、メモリの可視性のため、スレッドMはスレッドTのThread.sleep(1) 的时候,线程M 在 1ms 之后,便开始在 while(true) 循环中检查 td.isFlag()flagの値を時間内に読み取ることができないため、この時点で無限ループが発生します。
while(true)
td.isFlag()
の値を true に設定するため、M は 1000ms 後に td.isFlag() を検出します。値は true を返す必要があります。 code> を実行すると、最初の判定で true が返され、出力が生成され、while(true) ループから抜け出します。 Thread.sleep(1000) 的时候,M 在 1000ms 之后,开始在 while(true) 循环中检查 td.isFlag() 的值;但是 T 在 200ms 的时候,便将 flag 的值设为 true 了,所以,M 在 1000ms 之后检测 td.isFlag() 的值肯定是返回 true 的,那么第一次判断便会返回 true,产生输出并跳出 while(true)
flag の値を時間内に読み取るためには、 flag を キーワードで変更する必要があります: volatile リーリー
flagへのすべての変更が他のスレッドに即座に表示されるようになります。 の使用については、私のブログを参照してください: Java マルチスレッド (6): volatile キーワード volatile の使用
次の 3 つのコードを参照できます。 最初のコードは、マルチスレッドの可視性の問題により、無限ループを引き起こす可能性があります。 2 つ目は、この問題を解決するために synchronized を使用することです。これはほとんどの作業シナリオに適しています。 synchronized解决此问题,大多数工作场景用这个好第三个是使用volatile 3 つ目は、この問題を解決するために volatile を使用することです。ただし、このキーワードのみです。実際のシナリオでは制限が比較的大きいため、注意して使用してください
synchronized
まず、期待される効果を教えてください。質問は明確にしましょう
この期待は標準ではサポートされていません。コード内では、「メインスレッドの読み取り前にサブスレッドの書き込みが発生する」ことを保証するための処理は何も行われていません。
sleep(1000)
後で変更が表示されるのは単なる偶然です。JVM がメインスレッドに変更を表示するまで長時間待機する場合、またはメインスレッドに変更を表示させない場合でも、仕様には違反しません。あなたのプログラムをテストする必要があります
volatile
关键字的功能。但是 “把Thread.sleep(1)
换成Thread.sleep(1000)
就能获得预期效果” 这样做理解上是不对的。首先,程序中总共有两个线程,主线程(暂称 线程M)和
new Thread(td)
(暫定的にスレッド T と呼ばれます)。の値を書き込むとき、メモリの可視性のため、スレッドMはスレッドTの
Thread.sleep(1)
的时候,线程M 在 1ms 之后,便开始在while(true)
循环中检查td.isFlag()
flagの値を時間内に読み取ることができないため、この時点で無限ループが発生します。Thread.sleep(1000)
を記述するとき、M は 1000ms コードの後のwhile(true)
ループでtd.isFlag()
のチェックを開始します。 >; ただし、T は 200ms でflag
の値を
true
に設定するため、M は 1000ms 後にtd.isFlag()
を検出します。値はtrue
を返す必要があります。 code> を実行すると、最初の判定でtrue
が返され、出力が生成され、while(true)
ループから抜け出します。Thread.sleep(1000)
的时候,M 在 1000ms 之后,开始在while(true)
循环中检查td.isFlag()
的值;但是 T 在 200ms 的时候,便将 flag 的值设为true
了,所以,M 在 1000ms 之后检测td.isFlag()
的值肯定是返回true
的,那么第一次判断便会返回true
,产生输出并跳出while(true)
スレッド M がスレッド T の
flag の値を時間内に読み取るためには、 flag を キーワードで変更する必要があります:
その後、volatile
リーリーflagへのすべての変更が他のスレッドに即座に表示されるようになります。 の使用については、私のブログを参照してください: Java マルチスレッド (6): volatile キーワード
volatile
の使用次の 3 つのコードを参照できます。
リーリー リーリー リーリー最初のコードは、マルチスレッドの可視性の問題により、無限ループを引き起こす可能性があります。
2 つ目は、この問題を解決するために
synchronized
を使用することです。これはほとんどの作業シナリオに適しています。synchronized
解决此问题,大多数工作场景用这个好第三个是使用
volatile
3 つ目は、この問題を解決するためにvolatile
を使用することです。ただし、このキーワードのみです。実際のシナリオでは制限が比較的大きいため、注意して使用してください