単純なアプリケーションのロック
アトミック性を確保するためのロック付き(this.count ++コードは、クリティカル領域と呼ばれます)
実行の最初から最後まで不可分である何アトミックで、他のスレッドを同時に実行することはできません。
アトミック操作は、CASによって達成することができます
CAS(比較とスワップ):
CAS動作が変化し、変化が発生しない場合、古い第1の比較値の操作中に2つの入力値、古い値(運転前の目標値)と新しい値が、新しい値に切り替える前に、変更されていない必要無交換。
CASはcompareAndSwapXXX()メソッドを通じて、主に達成され、このメソッドの実装は、基礎となるクラスの危険なが関与する必要があることです
危険なカテゴリー: Javaは直接基礎となるオペレーティングシステムにアクセスするが、ローカルの方法でアクセスすることはできません。危険なクラスは、原子レベルのハードウェアオペレーションを提供します
ここでアトミック操作のブログの記述があります
https://my.oschina.net/xinxingegeya/blog/499223
危険なカテゴリを説明することがありブログ
http://www.cnblogs.com/mickole/articles/3757278.html
1 public class Counter{
2 private Lock lock = new Lock();
3 private int count = 0;
4 public int inc(){
5 lock.lock();
6 this.count++;
7 lock.unlock();
8 return count;
9 }
10 }
非リエントラントロック
次のように設計されています:
1 public class Lock{
2 private boolean isLocked = false;
3 public synchronized void lock() throws InterruptedException{
4 while(isLocked){
5 wait();
6 }
7 isLocked = true;
8 }
9 public synchronized void unlock(){
10 isLocked = false;
11 notify();
12 }
13 }
実際には、これは例えば、リエントラントロックではありません
1 public class Count{
2 Lock lock = new Lock();
3 public void print(){
4 lock.lock();
5 doAdd();
6 lock.unlock();
7 }
8 public void doAdd(){
9 lock.lock();
10 //do something
11 lock.unlock();
12 }
13 }
あなたがロックを取得するために、print()メソッドを呼び出すと、それはもはやので、このロックがある呼び出し、その後、あなたが呼び出す前にそれを解放する必要があり、doAdd()メソッドを呼び出すことはできませんまた、スピンロックと呼ばれていないリエントラントロック、。
リエントラントロック
次のように設計されています:
1 public class Lock{
2 boolean isLocked = false;
3 Thread lockedBy = null;
4 int lockedCount = 0;
5 public synchronized void lock()
6 throws InterruptedException{
7 Thread thread = Thread.currentThread();
8 while(isLocked && lockedBy != thread){
9 wait();
10 }
11 isLocked = true;
12 lockedCount++;
13 lockedBy = thread;
14 }
15 public synchronized void unlock(){
16 if(Thread.currentThread() == this.lockedBy){
17 lockedCount--;
18 if(lockedCount == 0){
19 isLocked = false;
20 notify();
21 }
22 }
23 }
24 }
比較的、リエントラント手段を話す:スレッドがスレッドがすでにと同期していることをすべてのロックにコードブロックを入力することができます
ロックを取得する最初のスレッドの実行印刷()メソッド、lockedBy現在のスレッド、このロックを取得するには、このメソッドの実行のそのスレッドは、add()メソッドの実装に等しく、同じ絶対必要は最初のロック(すなわち、コールを取得(スレッドがロックの印刷()メソッドが得られる呼び出すため、isLocked(= trueの場合)())lock.lock、条件があるためwhileループで満たされていない;しかしながら、非リエントラントロック区別lockedByであり(これは今のスレッドがロックを保持していることを意味します)、同じスレッドの呼び出しは追加するので、()メソッドが呼び出され、(印刷される)である)、で、現在ロックを取得し、この時間lockedCount変数、で、継続して待っていないこと数プラス1、すべてのロックの解除)(通知の実装前に、(呼び出しの回数をした数を取得するためにロックを解除)するとき。
このメソッドの実装では、第2のスレッドがlockedByがない第二のスレッドに等しいので、このメソッドを実装したいがある場合、(ブロック)待っている循環にスレッドリードは、待機()メソッドを実行し続けます。最初のスレッドがすべてのロックを解除するだけです(つまり、何回スレッドがロックを解除した回数のロック()メソッドを呼び出します()メソッドのロックを解除コール)、通知()メソッドの実装、唯一の第二のスレッド蚊帳の外であることを、続けます。
これは、再入可能ロック機能です。
リエントラント非リエントラントロックラッチコントラストは、単に:複数のリエントラントは、2つの属性をロック(1、ロック糸が得られ、図2に示すように、ロック取得の数)最初の属性判定によれば、そのスレッドが再びロックをロックを保持している場合は、(待機)をブロックされませんが、ロックされたプラス1(スレッドがロック(再入国を)持っていることを意味します)の数、スレッドアンロックの数だけロック完了の数(すなわち、第二の特性は0に等しい)は、他のスレッドを起動します。
Javaの一般的に使用される再入可能ロック
同期
java.util.concurrent.locks.ReentrantLock
他の
私たちはここに述べたロックまず、要求されたコード、リソース、またはデータのブロック操作の自分の時間でロック操作を行うための一つのスレッドだけが可能になります。最終結果は結果CPUの正しさを保証するためです。
非リエントラントロックの理解:
public class Test{
Lock lock = new Lock();
public void methodA(){
lock.lock();
...........;
methodB();
...........;
lock.unlock();
}
public void methodB(){
lock.lock();
...........;
lock.unlock();
}
}
ときの方法の取得のロックロックの期間ロックする時間はBの原子操作を行うために必要な、この場合には、方法Bと必要なロックので、アトミック操作を行うための方法、それは一緒に行きますB方式のデッドロック。リエントラントこの場合は非リエントラントロックと呼ばれるロックの問題があるでしょう。
ロック解除Bに待つ方法の必要性を実行するための方法が、方法Bのコードを実行し、完了したいロックにロックをロックする必要があります。ロックが解除されるラッチフロントは、他のコードブロックは、ロックをロックするために使用することができません。これは、非リエントラントロックによって決定されます。
我々は通常持っている必要がありますので、再入は、ロックを必要としています!!!!このようアトミック操作などの方法が、それはアトミック操作は、PS(ロックに同じロックを必要とする、彼らは同じ重要なリソースのために戦っている、Bメソッドを呼び出す必要があります。同じリソースの競合が重要なの本質であります同じロックの競合)
参考記事:
https://www.cnblogs.com/xdyixia/p/9383388.html
https://blog.csdn.net/qq_29519041/article/details/86583945
https://www.cnblogs.com/dj3839/p /6580765.html