0

ここにシナリオがあります

たとえば、2 つのスレッドが両方とも同じコードにアクセスし、そのコードには変数があります。

int a=200;

スレッド A が入り、その値を a=300 に変更します。

スレッド B がこの変数にアクセスすると、スレッド B は 200 または 300 を取得しますか?

4

5 に答える 5

2

2つのスレッドは、固定された順序で実行されることが保証されていません。Aでの操作は、Bでの操作に先行する可能性があります(ただし、操作が引き続き独自のスレッド内で順番に流れる場合)。

したがって、同期がないと、AはBがアクセスする前または後に値を変更する可能性があります。AがBの前にそれを変更した場合、Bは300を認識します。それ以外の場合、Bは200を参照します。

于 2012-10-16T05:29:59.100 に答える
1

以下の状態チャート図は、スレッドの状態を示しています。

ここに画像の説明を入力してください

  • 実行 可能—スレッドの優先順位に基づいてスレッドスケジューラによって実行のために順番が選択されるのを待機します。
  • 実行中—プロセッサはスレッドコードをアクティブに実行しています。ブロックされるまで実行されるか、この静的メソッドThread.yield()で自発的に順番を放棄します。コンテキスト切り替えのオーバーヘッドがあるため、yield()はあまり頻繁に使用しないでください。
  • 待機中—スレッドは、ファイルI / Oなどの外部処理が終了するのを待機している間、ブロックされた状態にあります。
  • スリープ—このオーバーロードされたメソッドを使用して、Javaスレッドを強制的にスリープ(一時停止)します。 Thread.sleep(milliseconds), Thread.sleep(milliseconds, nanoseconds);
  • I / Oでブロック—データのバイトの読み取りなどのI / O条件が変更された後、実行可能に移行します。
  • 同期時にブロック—ロックが取得されると実行可能に移動します。
  • Dead —スレッドは動作を終了しました。

あなたの例については、どのスレッドBが200または300を取るかわかりません。メソッドが同期されるため、両方のスレッドを同時に開始すると、スレッドBは200を参照する必要があります(1番目または300の場合)。

于 2012-10-16T05:38:13.937 に答える
1

コンパイラの最適化により、スレッドがデータをキャッシュし、最初のスレッドの変更が 2 番目のスレッドに表示されない場合があります。マルチスレッド環境での問題を回避するために、共有データに「揮発性」が使用される場所です。

補遺-さて、同期ではなく、スレッド全体の変数の変更の可視性について話していました。

于 2012-10-16T05:41:07.890 に答える
0

スレッドがコードに同時にアクセスする場合、jvmレベルのスレッド優先度に従って発生します。どのスレッドがコードにアクセスするかは保証できません。同期されている場合、スレッドBはスレッドAがリソースを解放するまで待機する必要があります。

于 2012-10-16T05:37:33.667 に答える
0

上記の実行の結果は、整合性モデルによって異なります。

シーケンシャル整合性モデルでは、実行の結果、すべての命令がグローバルな順序で実行されます。このような場合、threadB は値 300 を取得します。

ただし、最新のマシンは、すべての同期 (メモリ フェンス命令) 操作のみがグローバルな順次順序で発生する、より弱い整合性モデルを使用しています。

スレッド A のストアが完了した後にスレッド B のロードが発生した場合、スレッド B は値 = 300 を取得します。これは、キャッシュ コヒーレンス プロトコルによって保証されます。ただし、スレッド B のロード命令がスレッド A のストアの前またはストアと共に発生した場合 (何らかの最適化により)、スレッド B の共有変数の値は未定義です。これは、バス操作を介したスレッド B のロードとスレッド A のストアとの間の競合状態の結果です。

于 2012-10-16T05:40:53.957 に答える