問題タブ [memory-visibility]
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.
java - 静的変数はスレッド間で共有されますか?
スレッドに関する上位レベルのJavaクラスの私の先生は、私が確信が持てないことを言いました。
彼は、次のコードは必ずしもready
変数を更新するとは限らないと述べました。彼によると、2つのスレッドは必ずしも静的変数を共有するわけではありません。特に、各スレッド(メインスレッドとReaderThread
)が独自のプロセッサで実行されているため、同じレジスタ/キャッシュなどと1つのCPUを共有しない場合はそうです。もう一方は更新されません。
ready
基本的に、メインスレッドでは更新される可能性がありますが、では更新されない可能性があるReaderThread
ため、ReaderThread
無限にループする可能性があると彼は言いました。
彼はまた、プログラムが印刷することも可能であると主張し0
た42
。印刷方法はわかります42
が、わかりません0
。number
彼は、これは変数がデフォルト値に設定されている場合に当てはまると述べました。
静的変数がスレッド間で更新されることはおそらく保証されていないと思いましたが、これはJavaにとって非常に奇妙なことです。volatileを作成すると、ready
この問題は修正されますか?
彼はこのコードを示しました:
java - ビルダー/ファクトリパターンによるメモリの可視性の確保
次のクラス:
ビルダーパターンで使用できます。各プロパティは1回しか設定できないため、ビルド後は事実上不変です。あれは:
ただし、Pizza
スレッドセーフではありません。スレッドBがスレッドAによって設定された成分を認識できるという保証はありません。これを修正する方法はいくつかあります。
- メンバーを作成し
final
ます。ただし、ビルダーパターンを使用することはできません。 - メンバーへのアクセスを同期します。しかし、これは無駄のように思えます。なぜなら、それらは一度だけ書かれているからです。
- それらを作成します
volatile
。同期のように無駄を感じます。 - を使用し
AtomicReference
ます。 - 等。?
私の質問は、何らかのメソッドが呼び出された後、クラスメンバーが変更されないことをJVMに伝える最良の方法は何ですか?アクセスを同期して、JVMがロックを最適化することを信頼する必要がありますか?メンバーは設定後のように振る舞うべきだと私は知っているので、それはただ無駄に感じます。より良い解決策はありませんか?final
java - jvmの並べ替え/可視性効果テスト
いくつかのJava記事を書いている間、私はマルチスレッド環境で非同期オブジェクトのコスト削減の場合の並べ替えを再現しようとしています。重いオブジェクトがsynchonization/volatiles / finalsなしで構築され、他のスレッドがコンストラクター呼び出しの直後にそのオブジェクトにアクセスする場合。これが私が試したコードです:
-しかし、これまでのところ効果はありません。Windowsを搭載したさまざまな2、4、8コアのIntel / AMD PCを試し、数時間テストを実行しました-並べ替えの効果はありません-System.err.printf( "watcher%s sees.. 。")-呼び出されません。静的sharedArray [randomIndex]参照には、常に完全に構築された値が含まれます。
どうしたの?これを再現する方法は?
java - どのアーキテクチャ/OSで、他のスレッドがコンストラクター呼び出し後にデフォルトの非最終フィールド値を見ることができますか?
final 以外のフィールドのオブジェクト初期化が不十分な場合にメモリの可視性の問題を再現しようとしています (JLS 17.5 Final Field Semantics、FinalFieldExampleクラスの例)。「ただし、fy は最終的なものではありません。したがって、reader() メソッドは値 4 を表示することが保証されていません」
私はこのコードを試しました:
以前の同様のトピックと同様に、Windows を搭載したさまざまな PC (2 コアから 8 コアまで) と、サーバー側の Solaris 32 コア ボックスでさえ試しましたが、再現できませんでした: fx と fy は常に適切です。 -初期化。
私が答えを得たIntel/x86/x64アーキテクチャの場合、そのようなコンストラクタロジックの並べ替えを防ぐデフォルトのメモリ保証がほとんどあります。Solaris/sparc でも同じことが言えますか?
では、どのアーキテクチャ/OS でこの並べ替えを再現できるでしょうか?
java - 整数の非同期読み取りはJavaでスレッドセーフですか?
一部のOSS単体テストでこのコードが頻繁に見られますが、スレッドセーフですか?whileループは、invocの正しい値を確認することが保証されていますか?
いいえの場合; オタクは、これが失敗する可能性のあるCPUアーキテクチャを知っている人を指しています。
java - 揮発性変数とその他の変数
以下はクラシックからのものですConcurency in Practice
:
スレッド A が揮発性変数に書き込み、続いてスレッド B が同じ変数を読み取ると、揮発性変数に書き込む前に A に表示されていたすべての変数の値が、揮発性変数の読み取り後に B に表示されます。
私はこの声明を本当に理解できるかどうか確信が持てません。たとえば、この文脈におけるすべての変数の意味は何ですか? これはvolatile
、非揮発性変数の使用にも副作用があるということですか?
この声明には、私には理解できない微妙な意味があるように思えます。
何か助けはありますか?
java - この単純なスレッド化されたプログラムが動かなくなるのはなぜですか?
次の単純な Java プログラムを見てください。
あるマシンでは、「さようなら」と出力してすぐに終了しますが、別のマシンでは何も出力せず、永遠にそこにとどまります。なんで?
java - なぜこの Java プログラムは終了するべきではない (そして終了しない) にもかかわらず終了するのでしょうか?
今日、私の研究室で機密扱いの操作が完全に失敗しました。電子顕微鏡のアクチュエーターが限界を超え、一連の出来事の後で 1,200 万ドルの機器を失いました。障害のあるモジュールの 40,000 行以上を次のように絞り込みました。
私が得ている出力のいくつかのサンプル:
ここには浮動小数点演算がなく、符号付き整数が Java のオーバーフロー時に適切に動作することは誰もが知っているので、このコードに問題はないと思います。ただし、プログラムが終了条件に達しなかったことを示す出力にもかかわらず、プログラムは終了条件に達しました (到達したか、到達していないか?)。なんで?
これは一部の環境では発生しないことに気付きました。私は64 ビット LinuxでOpenJDK 6 を使用しています。
java - 配列変数の値をそれ自体に代入しますか?
この単純なコードがあります。
それは私が期待するものを出力します:
奇妙なのはa=a
inzzz()
です。外しても特に変化はないようです。なぜそこにあるのですか?