Java同時-volatileとsynchronized


volatile


機能

  • マルチスレッドの可視性を保証する
  • では、一部の再ソートが禁止されています.
  • volatileは軽量級synchronized
  • の任意の単一volatileに対する読み取り/書き込みは原子的(volatile=1/return volatile)であるが、複合型操作はサポートされていない.(volatile++操作)
  • とくせい


    volatileには以下の特性がある.volatileタグの変数は、読み込み操作時に最新の値に違いありません.どうして?1、lock接頭辞のサポート、volatileは変更操作のたびにメモリにリフレッシュし、読み取り操作もメモリに新しい値を取りに行くことを規定している.2、バスのサポート、複数のバストランザクションが同じ時刻に同じ時刻にメモリにアクセスできる権限は1つしかありません.そのため、スレッドが修正された限り、読み取り操作は必ず新しい値を取ります.###メモリの意味:volatile変数を読むと、JMMはスレッドに対応するローカルメモリを無効にします.スレッドは次にメインメモリから共用変写を読み込みます.volatile変数を書くと、JMMはそのスレッドに対応するローカルメモリの共用変数値をメインメモリにリフレッシュします.

    げんり

    instance = new Singleton(); // instance volatile 
    0x01a3de1d: movb $0×0,0×1104800(%esi);0x01a3de24: **lock** addl $0×0,(%esp);
    

    lock接頭辞の命令はマルチコアプロセッサの下で2つの操作をトリガーします
  • 現在のプロセッサキャッシュラインのデータをシステムメモリに書き込みます.
  • このメモリを書き戻す操作は、他のCPUでメモリアドレスをキャッシュしたデータを無効にします.

  • CPU依存キャッシュ整合性のサポート

    volatileルールテーブル


    2番目の操作がvolatileで書かれている場合、1番目の操作が何であれ、並べ替えることはできません.このルールは、volatile書き込み前の操作がコンパイラによってvolatile書き込み後に並べ替えられないことを保証します.最初の操作がvolatile読みである場合、2番目の操作が何であるかにかかわらず、並べ替えることはできません.このルールは、volatileの読み取り後の操作がコンパイラによってvolatileの読み取り前に並べ替えられないことを保証します.最初の操作がvolatileで書き、2番目の操作がvolatileで読む場合、並べ替えることはできません
    各volatile書き込み操作の前にStoreStoreバリアを挿入します.各volatile書き込み操作の後ろにStoreLoadバリアを挿入します.各volatile読み取り操作の後ろにLoadLoadバリアを挿入します.各volatile読み取り操作の後ろにLoadStoreバリアを挿入します.

    synchronized

  • 原子性.
  • スレッド同期のため、ある時点では、共有変数を1つのスレッドで操作するしかなく、マルチスレッド間の可視性
  • を保証する.

    使用

  • 通常の同期方法:ロックはthisロック
  • コードブロック:ロックはオブジェクトロック
  • である.
  • 静的同期方法:ロックは現在のClassオブジェクトロック
  • である.

    げんり

  • は、いずれもモニタオブジェクトを使用して動作するモニタrenterがコンパイル時にsynchronizedの開始位置に挿入され、モニタrexitがコンパイル時にsynchronizedの終了位置と者異常終了位置に挿入される.
  • 任意のオブジェクトがロックオブジェクトである場合、任意のオブジェクトはmonitorに関連付けられ、monitorが取得されると、monitorはロック状態になります.コマンドがmonitorenterに実行されると、そのmonitorの所有権を取得しようとします.

  • げんしせい

  • は、いくつかのカラム動作の原子性をロックによって実現する.しかし、性能が悪いと、ブロックが発生し、性能消費が増加します.
  • はCAS(compare and swap)によって実現され、この実装針は、付与動作に対して実行される.i++,
  • は、E(所望の値、すなわちキャッシュ/ローカルメモリ/ワークメモリのコピー)、V(現在の値)によって動作する.Eとメインメモリの値を比較すると、等しい場合は現在の値に新しい値が割り当てられます.
  • でABAの問題が発生し、他のスレッドが共有変数の値をBに変換してからAにすると、ローカルメモリの値をメインメモリにブラシすると、実行に成功します.しかし、結果は間違っているかもしれません.

  • ABAの問題はCAS+versionによって解決される.
  • すなわち、共有変数Vの値が1 A->2 B->3 Aであれば、このバージョン番号で制御することにより、ABA問題を巧みに解消することはできない.

  • CASは1つの変数しか処理できないことに注意し、ij=1 aを使用することができる場合、AtomicReferenceは参照オブジェクトの原子性を保証する.
  • CASはロックを追加する必要はありませんが、ループ検証はCPUの消費を増加させます.

  • コアコード

  • CASは操作を実現し、CASXXXX方法はCAS操作である.Unsafe.classはcコードを操作します.
  •     do{
            N = E+1;
        }while(CASXXXX((E,N));
    

    JAva concurrentパッケージのatomicクラス

    AtomicInteger  AtomicBoolean...(CAS, BAB )
    AtomicStampedReference  CAS ABA