問題タブ [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.

0 投票する
4 に答える
378 参照

java - Java Happens-Before およびスレッド セーフ

次のように HashMap をラップするクラスがあるとします。

このクラスは「Thread1」を介して初期化されます。ただし、put、get、printMap およびその他の操作は、「Thread2」によってのみ呼び出されます。

このクラスが次のようにスレッドセーフであることを理解しているのは正しいですか。

  1. マップへの参照は final と宣言されているため、他のすべてのスレッドはマップの初期状態を参照します (happens-before が確立されます)。

  2. put/get/printMap/etc は Thread2 によってのみ呼び出されるため、相互排除の必要はありません。

ありがとうございました

0 投票する
4 に答える
273 参照

java - Java - 前に発生 - 揮発性

私は以下のコードを持っています

複数のスレッドから同じオブジェクトを呼び出すとincrement()、次の出力が得られます (マシンによって異なる場合があります)。

最初の 3 つの数値(2 3 2) を考慮すると、スレッドが 3 を認識した場合、インクリメントが発生し、変数が揮発性であるため、その値は 3 以上である必要がありますがどのスレッドでも 2 にすることはできません。
ただ、ここで印刷行が並び替えられているようですが、その行を並び替えて正しいでしょうか?ここで何が欠けていますか?私はJDK 7(Eclipse)で実行しています

0 投票する
2 に答える
254 参照

java - Java - モニターのロック解除の事前発生関係

私は最近http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.htmlを読みました.Javaメモリモデルの多くの組み込みを明確に説明しています. ある特定の抜粋が私の注意を引きました。

私には明らかなようですが、http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.htmlと事前発生の定義を読んだ後、モニターのブロック解除について見つけることができたのは、スレッドは、他のスレッドが再びロックする前に発生するモニターのロックを解除します(これも完全に理にかなっています)。同期ブロック内のすべてのアクションがロック解除操作の前に発生する必要があるという明白な条件を JLS がどのように説明しているか説明できますか?

その他のコメント:

いくつかの回答に基づいて、皆さんが言っていることにさらにコメントを書きたいと思います。

  1. シングルスレッド内でのリオーダー

私が引用したソースからのいくつかの「真実」:

new A()100 の操作が含まれ、その後にヒープ上のアドレスが に割り当てられる場合a、コンパイラはそれらを単純に並べ替えてヒープ アドレスを割り当て、a通常の初期化に従うことができます (ダブル チェック ロックの問題)。

に変更できます

SOはmonitorexitprintステートメントで再注文しました(JLSに従っても有効です)

さて、私が言及した単純なケース:

コンパイラが最初に x または y を割り当てるのを止める理由はわかりません。x が最初に割り当てられるか y が割り当てられるかに関係なく、最終的な出力は変更されないため、それを止めるものはまったくありません。したがって、並べ替えは完全に可能です。

  1. モニター.ロック解除

print ステートメントが同期ブロックに「引き込まれている」例に基づいて、これを逆にしてみましょう。

コンパイラがこれを行うことを期待できます:

シングルスレッドの世界では完全に合理的に見えますが、これは間違いなく無効であり、 JLSに反します (引用元によると)。これについてJLS内で何も見つからない場合、なぜそうなるのでしょうか? そして明らかに、「プログラムの順序」に関する動機は今や無関係です。コンパイラーは、ステートメントを同期ブロックに「引き込む」などのリオーダーを行うことができるからです。

0 投票する
1 に答える
207 参照

java - volatile 参照によるオブジェクトの配列の安全な公開

次のコードは安全な公開を行いますか?

Happens -before here は、新しく作成されたすべてのオブジェクトに適用されますか、それとも配列自体にのみ適用されますか?

j内部に保持されるフィールドMyObjectがそうでなくてもfinal

0 投票する
3 に答える
160 参照

android - Android のこれら 2 つのスレッドで発生する前の関係がどのように確立されましたか

以下は、カスタム App クラスと MainActivity クラス コードのサンプル コード例です。

MainActivity クラス:

私がやろうとしているのは、INIT-THREAD で "i" の値を 100 に変更し、MAIN スレッドから値を読み取ろうとすることです。

onResume と handleMessage の "i" の値は MAIN スレッドで実行されているため、-100 になると予想していましたが、ログに出力される値は実際には 100 です。

ある意味で、私は誰もが通常の Java プログラムで行う古典的な間違いを再現しようとしていますが、Android はそれを賢く回避しているようです。

だから私は、アンドロイドが2つのスレッド間の事前発生関係をどのように達成しているかを理解することに興味があります.

0 投票する
2 に答える
427 参照

java - Java は揮発性フィールドの可視性をどのように管理しますか?

volatileこの Q では、Java がフィールドを可視化する正確な方法について具体的な詳細を探しています。

Javaのvolatileキーワードは、変数への書き込み操作が完了した直後に、その変数のリーダーに変数を「アクティブに」表示するために使用されます。これは、発生する前の関係の 1 つの形式です。書き込みの結果を、その変数のそのメモリ位置にアクセスして何らかの用途に使用する人に公開します。そして、使用すると、その変数に対する読み取り/書き込み操作がアトミックになります。 long&doubleについても同様です。他のすべての var 型への R/W は既にアトミックです。

書き込み操作の後に変数値を可視化するために Java が何をするかを知りたいですか?

例: 次のコードは、このディスカッションに関する回答の 1 つからのものです。

ブール値リテラルの読み取りと書き込みはアトミックです。上記のメソッドclose()が呼び出された場合、 as として宣言されていなくても、 closeasの値を設定するのはアトミック操作です。truevolatile

このコードでさらにvolatile行っていることは、この値への変更が発生した瞬間に確実に見られるようにすることです。

これをどのように正確volatileに達成していますか?

volatile 変数を操作するスレッドを優先することによって? もしそうなら - どのように、スレッドスケジューリングで、または読み取り操作を伴うスレッドを作成して、フラグを調べて、保留中のライタースレッドがあるかどうかを確認しますか? 「揮発性フィールドへの書き込みは、同じフィールドの後続のすべての読み取りの前に発生する」ことを認識しています。読み取り専用のスレッドにCPU時間を与える前に、揮発性変数に書き込み操作を行うスレッドの中から選択していますか?

これがスレッド スケジューリング レベルで管理されている場合 (これは疑問です)、揮発性フィールドに書き込みを行うスレッドを実行すると、見た目よりも大きな効果があります。

volatileJavaは変数の可視性をどの程度正確に管理していますか?

ティア。

0 投票する
2 に答える
679 参照

java - Java メモリ モデルの Happens-Before 関係

JLS ch17 Threads and Locksに関しては、「あるアクションが別のアクションの前に発生した場合、最初のアクションは2番目のアクションの前に表示され、順序付けられます」と書かれています。私は疑問に思う:

(1) 「先に注文した」とはどういう意味ですか? action_a が action_b の前に発生したとしても、実装によっては action_b の後に action_a を実行できるからですよね?

(2) action_a が action_b の前に発生する場合、action_a は action_b を見てはならないということですか? または、action_a が action_b を表示する場合と表示しない場合がありますか?

(3) action_a が action_b の前に発生せず、action_b が action_a の前に発生しない場合、action_a が action_b を表示する場合と表示しない場合があることを意味しますか?

(4) 周期的な事前発生はあり得ませんよね?

どんな答えでもいただければ幸いです:)