揮発性と同期の違い

アトミック(不可分)と可視性(視認性)

アトミックことを意味一瞬、一つだけのスレッドがコードの一部を実行することができ、監視対象の保護を経由してコードを。共有状態を更新するとき、それによって競合複数のスレッドを防止します。
可視性はより微妙で、それは共有データのロックを解除する前の変更は、別のスレッドが表示されているロックを取得するために作られていることを確認する必要があります。この同期メカニズムがなければ、多くの深刻な問題につながる変更前または一貫性のない、の値を見ることができる共有変数のスレッドが提供する可視性を確保します。

揮発性

それは修正変数は、メインメモリに直接アクセスコピーを保持しないのを。

Javaメモリー・モデルでは、あるメインメモリは、各スレッドが(例えば、レジスタ)それ自体のメモリを有します。パフォーマンスのために、スレッドは自分でメモリにアクセスする変数のコピーを保持します。そのような瞬間に、他のスレッドと同じ変数の可能な値のメモリ内のスレッドの値は、メモリ又は一貫性のない値の場合には、メインメモリに表示されます揮発性として宣言された変数は、この変数はいつでも他のスレッドに変更することが予想されることを意味するので、スレッドのキャッシュメモリであることができません。

利用シナリオ

あなただけの代わりに制限され、いくつかのケースでは、ロックの揮発性の変数を使用することができます。volatile変数のための理想的なスレッドセーフを提供し、あなたは、次の2つの条件を満たしている必要があります。
1)現在の値に依存しない変数への書き込み。
2)タグは、他の変数との不変量には含まれません。

揮発性が最も適した一つのスレッドを作成し、複数のスレッドが機会をお読みください。
複数のスレッドで同時に書き込みがある場合は、まだロックまたはその代わりに、スレッドセーフな容器や原子変数を使用する必要があります。

同期

これを修正するために使用される場合の方法またはブロックの時間を、可能である最大1つのスレッドが同じ期間内のコードを実行していることを確実にします

  1. オブジェクトがこの同期化(この)同期ブロックにアクセスするには、2つの並行スレッドで同じオブジェクトである場合、時間一つだけスレッドが実装されます。別のスレッドがコードブロックの実装が完了した後に、コードブロックを実行するために、現在のスレッドを待たなければなりません。
  2. しかし、スレッドが同期(本)同期ブロックのオブジェクトにアクセスするときに、別のスレッドが依然として非同期(本)同期ブロック内のオブジェクトにアクセスすることができます。
  3. スレッドが同期(本)同期ブロックのオブジェクトにアクセスするときに、特に重要である、同期コード・ブロックにアクセスするための同期、他のすべてのスレッド(この)の別の目的は、ブロックされます。
  4. スレッドが同期(本)シンクブロックのオブジェクトにアクセスするとき、そのオブジェクトのロックのオブジェクトが得られます。結果として、オブジェクトの同期コードセクションのすべてのオブジェクトにアクセスするための他のスレッドが一時的にブロックされています

違い

  1. volatile修飾子は、コードやメソッドの同期部分に作用する、変数です
  2. 揮発性メモリとメモリとの間の可変の同期の唯一のスレッド「メイン」値、およびロックとモニタの同期すべての変数の値をロック解除することによって同期化は、明らかに多くのリソースを消費するよりも揮発性同期。
  3. 同期閉塞スレッドを引き起こす可能性があり、揮発性が閉塞スレッドが発生しません。
  4. 視認性の揮発性データを確保するが、原子性を保証することはできません。それは、共通のメモリにプライベートデータメモリとの同期を行うことになるため、原子は、間接的に可視またはを確保するために、保証と同期させることができます。
  5. 変数揮発性フラグは、コンパイラ最適化されないであろう。マークは、可変最適化コンパイラを同期させることができます。

二つの側面を構成する原子のスレッドの安全性と可視性は、Java同期メカニズムは、スレッドセーフを保証するために、これらの二つの側面を中心に構築されています。
複数のスレッドでvolatileキーワードの主な用途は、インスタンス変数が変更されて知覚することができる、および使用される最新の値はどこで入手でき、共有変数を読み込み、複数のスレッドを使用しているとき、あなたは最新の値を取得することができます。

キーワード揮発プロンプト各スレッドは、このように同期データの視認性を確保し、共有メモリ変数の代わりに、プライベート・メモリを読み取ることから読み出します。しかし、次の点に注意してくださいあなたはインスタンス変数内のデータを変更した場合

例えば:I + 1、そのような動作は、実際にアトミック操作ではない私は、すなわち、I ++ =、それはスレッドセーフではありません。次のように私は、発現分解の手順を++:
1)私はメモリから値をとります。
2)iの値を計算;
3)、iの値がメモリに書き込まれます。
時間は2価値のステップで計算した場合、別のスレッドは、読み出しデータが汚れて表示されます。この時点で、iの値が、名前を変更することができます。解決策は、synchronizedキーワードを使用することです。だから、プロセス自体は揮発性の原子データではなく、時間内に読み込みを強制し、メインメモリ効果にデータを書き込みます。

参考:
https://www.jianshu.com/p/0a6ca9c7695b(JAVAクリアランスの問題-Volatileと同期)
https://blog.csdn.net/it_manman/article/details/7949​​7807(揮発性との間の差同期a)の
HTTPS: //blog.csdn.net/mccand1234/article/details/52139319(Javaのメモリモデル)
https://www.cnblogs.com/hrlizhi/p/9418009.html(volatileキーワードをマルチスレッド)
HTTPS://ブログ。 csdn.net/vking_wang/article/details/9982709(揮発性該当シーン)
https://www.jianshu.com/p/c6f190018db1(命令の並べ替え)

おすすめ

転載: blog.csdn.net/mccand1234/article/details/91345168