問題タブ [happens-before]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
volatile - 揮発性テストは、JLS の事前発生機能を満たしていませんでした
メインを実行
出力
違反の前に発生 p = 736;q = 827
違反の前に発生 p = 4635;q = 4657
違反の前に発生 p = 6421;q = 6440
違反の前に発生 p = 8719;q = 8803
java - Java メモリ モデル: 揮発性変数と事前発生
事前発生関係が揮発性変数でどのように機能するかを明確にしたいと思います。次の変数があるとします。
とスレッド A:
とスレッド B:
次のステートメントは、Java メモリ モデル (JMM) に従って正しいですか? そうでない場合、どのような解釈が正しいでしょうか?
i = 1
常に前発生v = 2
v = 2
JMM での事前vDst = v
発生は、それが時間内に実際に発生した場合にのみ発生します。i = 1
iDst = i
JMM での事前発生 (予測iDst
可能に割り当てられる1
) がv = 2
実際に前に発生vDst = v
した場合i = 1
それ以外の場合、との間の順序iDst = i
は未定義であり、 の結果の値もiDst
未定義です
ロジックの間違い:
JMM には「ウォール クロック タイム」の概念はなく、 との順序ガイドとして同期順序に依存する必要がv = 2
ありvDst = v
ます。詳細については、選択した回答を参照してください。
java - .awaitTermination() はエグゼキューターで行われた作業で事前発生を確立しますか?
私が何年も持っていた質問: この疑似コードでは、
.awaitTermination()
コードAとBの間 で事前発生を確立すると文書化されていません。そうでない理由はありますか?
ExecutorServiceと並行パッケージの javadoc は、タスクとサブミットされる前に実行された作業との間で発生する前に定義しますが、呼び出しが成功した後のエグゼキュータータスクとコードの間では定義しません。.awaitTermination()
文書化された事前発生関係を活用するためにコードを再構築する方法について、設計上の批評を求めているわけではないことに注意してください。ここでの私の質問は、この状況でドキュメントが事前発生について言及していない理由はありますか?
(非常に適切なタイトルにもかかわらず、これは22665198の複製ではないことに注意してください。)
java - java.io.FileInputStream は、同期ブロック内からのみプライベート volatile 変数 'closed' にアクセスします。なんで?
私の知る限り、同期内で行われた変更が同じロックで同期している次のスレッドに表示される「前に起こる」状態。
冗長ではありませんか?
java - エグゼキュータ サービスによる同時配列アクセス
配列要素はワーカー間で正しく公開されていますか?
大きな配列があるとします (任意のアトミック データ型であるため、long
orではありませんdouble
)。
- コンストラクターに渡す配列を埋めるワーカーを作成し、
- ワーカーをエグゼキューターに送信し、完了するまで待ちます (例:
future.get()
)。ワーカーは何も返しません。それは私の配列を埋めるだけです。 - 次に、コンストラクターに同じ配列を持つ別のワーカーをすぐに作成して送信します。最新の値が表示されますか?
言い換えれば、前のワーカーの最後の書き込みが、次のワーカーの最初の読み取りの前に発生することが保証されていますか?
参照が既に持っているものと同じであっても、代わりに(またはベストプラクティスなどのために)最初のワーカーに配列を返させる必要がありますか?
[編集] いくつかの背景: 私はbyte
配列またはshort
配列のいずれかを使用します。これらは画像を表し、それぞれ最大 5 億個の要素を使用します。各要素に対して簡単な計算を実行します。
java - 前発生および揮発性変数
以下は、JMM の 3 つの「事前発生」ルールです。私の質問はこれら 3 つのルールのみに関連しているため、他のルールは記載していません。
- ロック規則を監視します。モニター ロックのロック解除は、同じモニター ロックの後続のすべてのロックの前に行われます。
- スレッド開始規則。スレッドでの Thread.start の呼び出しは、開始されたスレッドのすべてのアクションの前に発生します。
- 中断ルール。別のスレッドで割り込みを呼び出すスレッドは、割り込みを受けたスレッドが (InterruptedException をスローするか、isInterrupted または interrupted を呼び出すことによって) 割り込みを検出する前に発生します。
質問
第 1 のルールの質問 - 2 つのスレッド A と B が同期したコード ブロックを持っているとします。最初のルールは、変数が volatile として宣言されていなくても、スレッド A の同期ブロックに設定された変数は、スレッド B の同期ブロックのコードから見えるということですか?
2 番目のルールの質問- スレッド A がスレッド B を開始するとします。2 番目のルールは、変数が volatile として宣言されていなくても、start() を呼び出す前に親スレッドに設定された変数がスレッド B に見えることを意味しますか?
3 番目の規則の質問- スレッド A がスレッド B に割り込むとしましょう。揮発性?
最後に、もう 1 つ質問します。
- BlockingQueue のドキュメントでは、次のように述べられています。
メモリの一貫性の影響: 他の並行コレクションと同様に、オブジェクトを BlockingQueue に配置する前のスレッド内のアクションは、別のスレッド内の BlockingQueue からのその要素へのアクセスまたは削除に続くアクションの前に発生します。
これは、変数が揮発性として宣言されていなくても、オブジェクトをブロック キューに入れる前にスレッド A に設定された変数が、キューからオブジェクトをデキューした後にスレッド B に見えることを意味しますか?
基本的に上記の質問を通じて、これらの場合に変数を volatile として宣言する必要がないように、これらのイベントの後にメモリ フラッシュが発生するかどうかを理解しようとしています。