Java同期:同時性の3つの特性

2836 ワード

Java同時三大性質
Javaメモリモデルには、原子性、秩序性、可視性の3つの性質がある.
原子性:1つの操作または複数の操作は、すべて実行され、実行されたプロセスがいかなる要因によっても中断されないか、実行されないかのいずれかです.複数のスレッドが一緒に実行する場合でも、1つの操作が開始すると、他のスレッドに干渉ことはない.
秩序性:すなわち、プログラムの実行順序はコードの前後順に実行する.
≪可視性|Visibility|emdw≫:複数のスレッドが同じ変数にアクセスすると、スレッドがこの変数の値を変更すると、他のスレッドは変更された値を表示できます.
げんしせい
例えば、Aは自分の口座から1000元をBの口座に振り込みたいと思っています.それがAから振り替えられ、振り替えが終わるまでの過程を一つの事務と呼ぶ.このトランザクションでは、次の操作を行います.
  • Aの口座から1000元を差し引いた.Aの口座が3000元あったら、今は2000元になります.
  • Bの口座に1000元加算します.Bの口座が2000元あったら、今は3000元になります.

  • Aの口座から1000元を差し引いた場合、停電などの事故が発生し、振替事務が意外に終了したが、Bの口座には1000元も増えていない.では、この操作が失敗したと言って、ロールバックします.
    私たちはこのような一緒に成功するか、一緒に失敗する操作を原子的な操作と呼んでいます.
    トランザクションをプログラムと見なす場合は、完全に実行されるか、完全に実行されないかのいずれかです.この特性を原子性と呼ぶ.
    正確な例を挙げます.
    int x = 1; 
    int y = x;  
    x++;
    x += 1; 

    以上の4つのコードは、一目で原子的な操作であるが、実は中には1つ目の文だけが原子的な操作である.
    まず、コンピュータの動作方法について説明します.
    私たちがプログラムを実行するとき、CPUはプログラムの各命令を実行します.プログラムを実行する過程で、メモリに保存されている一時的なデータに関連するに違いありません.これには、CPUが実行するコマンドの速度が、メモリからのデータの読み出しやメモリへのデータの書き込みよりもはるかに速いという問題がある.いつでも操作データがメモリから読み書きされると、プログラムの実行速度が大幅に低下するため、キャッシュが作成されます.
    プログラムの実行中に、演算に必要なデータをメモリからCPUのキャッシュにコピーし、CPUが計算すると、そのキャッシュから直接データを読み書きすることができます.演算を終了してから、キャッシュ内のデータをメモリに書き込みます.
    さっきの4つのコードを見てみましょう.
    int x=1;// x   1,        10     
    int y=x;//        ,   x  ,   x     y      ,              ,              
    x++;
    x+=1;//       3   ,    x  ,     1,          

    しかし、最初のコードに注意してください.
    int x=1;//  x   32    ,           ,  16   ,  16   ,          

    可視性
    可視性の場合、Javaはvolatileキーワードを提供して可視性を保証します.
    共有変数がvolatileによって修飾されると、値の変更が保証され、すぐに他の共有スレッドに表示され、次にロードされるとキャッシュから値を取るのではなくメモリから値を再取得しますが、volatile変数は原子性を保証できません.
    原子性を保証するにはsynchronizedとReentrantLockを使用します.可視性も原子性も保証できますが、オーバーヘッドが大きくなります.
    秩序性
    Javaでは、コンパイラとプロセッサが命令を再ソートすることを許可します.再ソートとは、単純な点で命令の実行順序を変更することです.並べ替えは、単一スレッドの実行には影響しませんが、マルチスレッドの同時実行には影響します.
    同様にsynchronizedとReentrantLockを使用すると、秩序性も保証されます.
    しかし、Javaメモリモデルには先天的な秩序性がある追加のものについてお話しします.happens-before原則とも呼ばれる.
    happens-before原則:
  • プログラム順序規則:1つのスレッド内で、コード順序に従って、前に書く操作は、後に書く操作
  • で先に発生する.
  • ロック規則:1つのunLock操作は、同じロックに対するlock操作
  • の後に先行する.
  • volatile変数規則:1つの変数に対する書き込み操作は、この変数に対する読み取り操作
  • の後に先行する.
  • 伝達規則:操作Aが操作Bに先行する、操作Bが操作Cに先行する場合、操作Aが操作C
  • に先行して発生することが分かる.
  • スレッド起動規則:Threadオブジェクトのstart()メソッドは、このスレッドの各動作
  • において先行する.
  • スレッド割込みルール:スレッドinterrupt()メソッドの呼び出しは、割込みスレッドのコードによって割込みイベントが検出された発生
  • に先行する.
  • スレッド終了規則:スレッド内のすべての操作はスレッドの終了検出に先行して発生し、Thread.ジョン()メソッド終了、Thread.isAlive()の戻り値手段は、スレッドが
  • の実行を終了したことを検出する.
  • オブジェクト終端規則:オブジェクトの初期化完了が彼のfinalize()メソッドの開始
  • に先行して発生する
    変換元:https://www.cnblogs.com/dolphin0520/p/3920373.html
    転載先:https://www.cnblogs.com/Fill/p/9382292.html