Java volatileの基本原理

はじめに

  1. Java言語でvolatileによって変更された変数は、スレッドシナリオでの可視性を保証できます。
  2. プロセッサ命令並べ替え防ぐため、視認性に問題があるだろう、マルチスレッド環境で命令再配置を

つまり、揮発性変数xにアクセスできるスレッドABがあります。
スレッドAがxを変更すると、スレッドBは変数xに再度アクセスして、xの最新の値を取得できます。
不揮発性変数はこれを保証できません。

可視性の原則

揮発性変数修飾子が適切に使用されている場合、スレッドコンテキストの切り替えとスケジューリングが発生しないため、同期よりも使用および実行の方が安価です。

volatile変数で装飾された共有変数が書き込まれると、ロックアセンブリコードが使用されます。ロックプレフィックス付きの命令は、マルチコアプロセッサで2つのことを引き起こします。

  1. 現在のプロセッサキャッシュラインのデータがシステムメモリに書き戻されます。
  2. このメモリへの書き戻し操作により、他のCPUのメモリアドレスにキャッシュされたデータが無効になります。(他のCPUはキャッシュスニッフィングによってキャッシュを無効にします)

再配置を防止する原理

  1. 各揮発性書き込み操作の前にStoreStoreバリアを挿入し、書き込み操作の後にStoreLoadバリアを挿入します
  2. 各揮発性読み取り操作の前にLoadLoadバリアを挿入し、読み取り操作の後にLoadStoreバリアを挿入します。

Javaメモリバリア

  • Javaのメモリバリアは通常4つのタイプと呼ばれます。つまり、LoadLoad、StoreStore、LoadStoreです。StoreLoadは実際には上記の2つの組み合わせであり、一連のバリアとデータ同期機能を備えています。
  • LoadLoadバリア:このようなステートメントLoad1; LoadLoad; Load2の場合、Load2によって読み取られるデータと後続の読み取り操作にアクセスする前に、Load1によって読み取られるデータが読み取られていることを確認してください。
  • StoreStoreバリア:このようなステートメントStore1; StoreStore; Store2の場合、Store2以降の書き込み操作が実行される前に、Store1の書き込み操作が他のプロセッサーから見えることを確認してください。
  • LoadStoreバリア:このようなステートメントLoad1; LoadStore; Store2の場合、Store2および後続の書き込み操作がフラッシュされる前に、Load1によって読み取られるデータが読み取られることを確認してください。
  • StoreLoadバリア:このようなステートメントStore1; StoreLoad; Load2の場合、Load2および後続のすべての読み取り操作が実行される前に、Store1の書き込みがすべてのプロセッサから見えるようにします。そのオーバーヘッドは4つの障壁の中で最大のものです。ほとんどのプロセッサ実装では、このバリアは全能バリアであり、他の3つのメモリバリアの機能を組み合わせています

見積もり

https://www.jianshu.com/p/2ab5e3d7e510
https://www.cnblogs.com/chenssy/p/6379280.html

元の記事を17件公開 24 件を獲得 28万回以上表示

おすすめ

転載: blog.csdn.net/qq_22956867/article/details/79400428