マルチスレッド高同時プログラミング(2)--再入力ロックの紹介とカスタマイズができます。
10020 ワード
背景:
重入可能とは何ですか?再入力できるということは、あるスレッドはすでにロックを獲得していますが、再度ロックを取得することができます。ロックを再入力することができるのは、デッドロックを避けるためであり、javaでは、synchronizedとRentrant Lockは再入力可能です。
再ロック不可とは、現在のスレッドがある方法を実行してロックを取得した場合、再びロックを取得しようとすると、ブロックされていないことになります。以下のスレッドがtest 1()を実行する方法はまずロックを取得し、次にtest 2()を実行する方法はtest 2()の論理を実行できなくなり、先にロックを解除しなければなりません。
プロセス:は、ロック占有識別、記憶スレッド、スレッドロック保持数を定義する。 はロックを使用しています。現在のスレッドがメモリスレッドと等しくないかどうかを判断し、条件がログイン待ちに一致していない場合は、占有標識、記憶スレッドが現在のスレッド、スレッドロック数+1に変更されます。 リリースロック:現在のスレッドが記憶スレッドに等しいかどうかを判断し、条件が一致したらスレッドのロック数-1、スレッドのロック数=0の時に、占有標識を修正して、待ちスレッドを起動し、記憶スレッドをnullにセットする。
重入可能とは何ですか?再入力できるということは、あるスレッドはすでにロックを獲得していますが、再度ロックを取得することができます。ロックを再入力することができるのは、デッドロックを避けるためであり、javaでは、synchronizedとRentrant Lockは再入力可能です。
//synchronized
private void test() {
//
synchronized (this) {
while (true) {
//
synchronized (this) {
System.out.println("ReentrantLock!");
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//ReentrantLock
Lock lock = new ReentrantLock();
private void test1() {
lock.lock();
try {
test2();
} finally {
lock.unlock();
}
}
private void test2() {
lock.lock();
try {
System.out.println("ReentrantLock!");
} finally {
lock.unlock();
}
}
一.カスタムはロックを再入力できません。再ロック不可とは、現在のスレッドがある方法を実行してロックを取得した場合、再びロックを取得しようとすると、ブロックされていないことになります。以下のスレッドがtest 1()を実行する方法はまずロックを取得し、次にtest 2()を実行する方法はtest 2()の論理を実行できなくなり、先にロックを解除しなければなりません。
//
class Lock {
//
private boolean isLocked = false;
//
public synchronized void lock() {
while (isLocked) {//
try {
this.wait();//
} catch (InterruptedException e) {
e.printStackTrace();
}
}
isLocked = true;//
}
//
public synchronized void unLock() {
isLocked = false;//
notify();//
}
}
============ ===========
Lock lock = new Lock();
public void test1() {
lock.lock();
test2();
lock.unLock();
}
private void test2() {
lock.lock();
//...
lock.unLock();
}
二.カスタムでロックを再入力できます。プロセス:
//
class ReLock{
//
private boolean isLocked = false;
private Thread lockedBy = null; //
private int holdCount = 0;
//
public synchronized void lock() throws InterruptedException {
Thread t = Thread.currentThread();
while(isLocked && lockedBy != t) {
wait();
}
isLocked = true;
lockedBy = t;
holdCount ++;
}
//
public synchronized void unlock() {
if(Thread.currentThread() == lockedBy) {
holdCount --;
if(holdCount ==0) {
isLocked = false;
notify();
lockedBy = null;
}
}
}
public int getHoldCount() {
return holdCount;
}
}
============== ===============
public class LockTest {
ReLock lock = new ReLock();
public void test1() throws InterruptedException {
lock.lock();
System.out.println(lock.getHoldCount());
test2();
lock.unlock();
System.out.println(lock.getHoldCount());
}
//
public void test2() throws InterruptedException {
lock.lock();
System.out.println(lock.getHoldCount());
//...................
lock.unlock();
System.out.println(lock.getHoldCount());
}
public static void main(String[] args) throws InterruptedException {
LockTest lockTest= new LockTest();
lockTest.test1();
Thread.sleep(1000);
System.out.println(lockTest.lock.getHoldCount());
}
}