原子性を保証することはできません秩序を確保するために、なぜ揮発性

メモリモデルの3つの特性のために:順序、アトミック性、可視性。

我々は、すべての揮発性の可視性と秩序を確保することを知っているが、原子性を保証することはできませんが、なぜ?

 

アトミック、発注、可視性

1、原子性:

;「不可分」 - (1)原子を表し手段
(2)全体の動作が中断されないスレッドスケジューラの動作がアトミックであると考えることができますアトミックであるクロスマルチスレッド操作を拒否し、単核又は多核か、原子量を有する、それを操作するために同じ時間だけスレッド例えば、A = 1つのアトミック操作が、++、A + = 1とアトミック操作ではありません。

図2に示すように、可視

他のスレッドへのメモリの可視性でのスレッドの実行結果。

修正揮発性変数は、この変数が書き込まれた後、アセンブリ命令は、LOCKプリフィックス命令は、この命令の追加は二つのことにつながるがあります。

  • 行われた変更の後に強制的に現在のプロセッサのデータ・キャッシュ・ラインが書き込まれるシステム・メモリに戻っ
  • ライトバックメモリ操作が原因となり、他のプロセッサが無効なメモリアドレス、メモリからの再読み込みキャッシュします。

3、秩序

スレッド内で観察され、すべての操作は(すなわち、命令は及びシーケンシングスレッドのプログラムの実行結果の前に任意の再配列の違いが発生することはありません)注文しています。スレッド内の他のスレッドは、すべての操作が乱れている観察は、障害があるため、コマンド並べ替えです。Javaのメモリモデルでは、コンパイラやプロセッサの命令の並べ替えが可能、リオーダリング処理はシングルスレッドプログラムの実施に影響を与えませんが、それは、複数のスレッドの同時実行の精度に影響を及ぼします。

 

第二に、二つの質問スレッドセーフ実行およびメモリ制御見えます

実行制御(同期):制御コードのみを順次行うことができる(のみ実行のスレッド後に行うこと)、または実行マルチスレッドであってもよいです。

:メモリ制御(揮発性)の視認性を他のスレッドにメモリ視認性のスレッドの実行結果。特定のスレッドの実行において、まず、メインメモリスレッドローカル(CPUキャッシュ)にデータをコピーする操作後の結果は、ローカルメインメモリへのスレッドからブラシを完了する。

揮発性および二つのキーワード上記の二つの効果を同期させます。

  • 同時に複数のスレッドが現在の変数、ロックメソッド、クラス、および他のスレッドを得ることができるようにアクセス、それは、同時実行を同期させることができないことはできないキーワードを同期synchronized作成するメモリバリアをすることを確実にするために、メモリバリア命令すべてのCPUの動作結果は直接になりますメインメモリにブラシそれによってメモリ動作の視認性を確保するだけでなくなり、ロックの最初のスレッドのすべての操作が、その後に得られ得られる起こる、前スレッドにロックを作動セキュリティと秩序、可視性、アトミック;
  • 現在のスレッドの値を強制的に揮発性がライトバックモードメモリと、この値は、なぜ議論原子の次の部分に特定の特性を保証することはできません、整然とを確保命令再配置を無効にすることにより、その視認性を確保するために、他のスレッドで無効であるように改変しました。

 

第三に、なぜ揮発性の原子性を保証することはできません

かもしれない、独自のアトミック操作のため、ので、私= 1この割り当てのために、マルチスレッドプログラムには矛盾が存在しない、しかし、私はアトミック操作を保証するものではありませんでも、volatileキーワードの変更で、この複雑な操作のため++データの不整合が生じます。

 プライベート 揮発 int型私= 0 ; 
 I ++;

あなたはこの操作の最終結果を実行するために500個の同時スレッドを有効にした場合、私は500未満である++します

私は++操作は3つのステップに分けることができる:

      1、スレッドは、iの値読み込み

      2を、iが算出する自己増力

      3、バックiの値を更新します

いくつかのオンラインのブログがある説明:

自スレッドのI次に、I = 5時間を想定し、iは、メインメモリから読み出された値の2件のスレッドがあり、この場合に格納されたiの値は、2つのスレッド5であります計算では、Bはまた、私が計算することにインクリメントされ、バック揮発性が原子性を保証することはできませんように、私は(計算された2つのスレッドが7を終了する必要があります)6ホストされている2つのスレッドの最後の更新値に、この時間。

私はそれを理解しています。

私は、操作のために、私は、ああスレッド間でさえA.可視であるべきで、揮発性の変数を変更しているので、B 2つのスレッドが同時にiの値が5で読み取られ、私は、スレッドAを実行している場合動作は、iの再読み込み新しい値に無効と力Bであることを、私はスレッドを読み取るBの値に設定された後6は、次にああインクリメントオペレータ魚であろうあります。

その後、他のブログを参照するには、最終的に考え出しました:

図1に示すように、スレッドは、I読み出し

2、TEMP = I + 1 

。3、I = TEMPを

場合I = 5 A、Bは、2つのスレッドを読み取るとき、Iの値を、次に、スレッドは実行TEMP = I + 1この時点で留意すべき操作、Iの値が変更されていないし、またBをスレッド実行TEMP = I + 1つの動作は、この場合には、二つのスレッドに格納されたB注意I値である。5TEMPの 値が6、スレッドが実行I = TEMP(6)の操作を、この時点で、私は、メインメモリに直ちにフラッシュ値と保存された他のスレッド通知iの値が無効である場合、Bのスレッドが再読み込みする必要が私の、時間保存されたスレッドBの値iがある6、スレッドBを保存しながら、温度をもそれはまだ6、実行及びB Iのスレッド= TEMP(6)、以下予想される結果をもたらす1

 

四の違い、揮発性および同期

  1. 揮発性の性質はレジスタにJVM現在の変数の値を語っている(ワーキングメモリ)が、定かではメインメモリから読み出される必要がある。同期現在の変数は、現在のスレッドのみが変数にアクセスすることができ、ロックされ、他のスレッドが生きてブロックされています。
  2. 同期変数は、方法で使用することができ、クラスレベル、揮発性のレベルは、変数で使用することができます
  3. 可視性とアトミック性を保証して同期されている変数を変更し、揮発性の視認性のみ変数を変更する達成することができ、原子性を保証するものではありません。
  4. 同期閉塞スレッドを引き起こす可能性があり、揮発性が閉塞スレッドが発生しません。
  5. 揮発性の変数は、コンパイラの最適化をラベル付けされていません。マークが可変の最適化コンパイラを同期させることができます

 

参考文献:

Javaのメモリモデル:https://blog.csdn.net/suifeng3051/article/details/52611310

揮発性の違いを同期:https://blog.csdn.net/it_manman/article/details/7949​​7807

なぜ揮発性は保証されませんアトミック:https://blog.csdn.net/xdzhouxin/article/details/81236356  https://blog.csdn.net/ACreazyCoder/article/details/82047970

おすすめ

転載: www.cnblogs.com/simpleDi/p/11517150.html