ReentrantLockのConditionによるスレッド間の通信
2858 ワード
Conditionはスレッド間の通信を実現し,awatとsignalの2つの方法によってスレッド間の通信連携を実現することができる.
ここではConditionを利用して、3つのスレッドを開いて、スレッドを順番にA、B、Cを循環印刷させる機能を実現します.
プライマリ・コードは次のとおりです.
コンソール印刷:
まとめ:
ReentrantLockは独占ロックで、1つのスレッドがロックを手に入れた後に解放しなければ、もう1つのスレッドはロックを手に入れられないに違いないのでlock.lock()とlock.unlock()の間には、ロックを解除する操作が1回ある可能性があります(同様に、ロックを取得する操作も必ず1回あります).take()もput()もlockに入っています.ロック()後にロックを解除できる唯一の操作はawait()です.すなわちawait()操作は実際にはロックを解放し、スレッドを掛け、条件が満たされると起動し、再びロックを取得することである.これはwaitとnotifyに似ています.waitもロックを解放します.sleepはロックを解放しません.
ここではConditionを利用して、3つのスレッドを開いて、スレッドを順番にA、B、Cを循環印刷させる機能を実現します.
プライマリ・コードは次のとおりです.
static final ReentrantLock lock = new ReentrantLock();
static AtomicBoolean firstA = new AtomicBoolean(true);
static class PrintRunable implements Runnable{
private String str;
private Condition await;
private Condition signal;
public PrintRunable(String str, Condition await, Condition signal) {
this.str = str;
this.await = await;
this.signal = signal;
}
@Override
public void run() {
// A ,
if (firstA.get() && "A".equals(str)) {
lock.lock();
try {
System.out.println(str);
firstA.getAndSet(true);
TimeUnit.SECONDS.sleep(1);
signal.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
while (true) {
while (true) {
lock.lock();
try {
//
await.await();
System.out.println(str);
TimeUnit.SECONDS.sleep(1);
//
signal.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
}
テスト:@Test
public void reentrantLockTest() throws Exception {
final Condition condition1 = lock.newCondition();
final Condition condition2 = lock.newCondition();
final Condition condition3 = lock.newCondition();
Thread a = new Thread(new PrintRunable("A",condition1,condition2));
Thread b = new Thread(new PrintRunable("B",condition2,condition3));
Thread c = new Thread(new PrintRunable("C",condition3,condition1));
b.start();
c.start();
a.start();
b.join();
a.join();
c.join();
}
コンソール印刷:
A
B
C
A
B
C
A
B
C
まとめ:
ReentrantLockは独占ロックで、1つのスレッドがロックを手に入れた後に解放しなければ、もう1つのスレッドはロックを手に入れられないに違いないのでlock.lock()とlock.unlock()の間には、ロックを解除する操作が1回ある可能性があります(同様に、ロックを取得する操作も必ず1回あります).take()もput()もlockに入っています.ロック()後にロックを解除できる唯一の操作はawait()です.すなわちawait()操作は実際にはロックを解放し、スレッドを掛け、条件が満たされると起動し、再びロックを取得することである.これはwaitとnotifyに似ています.waitもロックを解放します.sleepはロックを解放しません.