Condition条件唤醒
-
在并行程序中, 避免不了某些线程要预先规定好的顺序执行, 例如, 先新增再修改, 先买后卖, 先进后厨 … 对于这类场景, 使用JUC的Condition对象非常合适
-
JUC中提供了Condition对象, 用于让指定线程等待与唤醒, 按照预期顺序执行, 它必须和ReentrantLock重入锁配合使用
-
Conddition用于替代wait() / notify()方法
- notify 只能随机唤醒等待的线程, 而Condition可以唤醒指定的线程, 这样有利于更好的控制并发程序
-
Condition核心方法
- await() - 阻塞当前线程, 直到signal唤醒
- signal() - 唤醒被await的线程, 从中断处继续执行
- signalAll() - 唤醒所有被await() 阻塞的线程
示例代码
package com.ygq.thread.threadPool;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author :GQ.Yin
* @date :Created in 2019/8/15 14:31
* @description:${description}
* @version: $version$
*/
public class ConditionSample {
public static void main(String[] args) {
final ReentrantLock lock = new ReentrantLock(); //condition对象必须配合lock一起用
final Condition c1 = lock.newCondition(); //创建condition对象
final Condition c2 = lock.newCondition(); //创建condition对象
final Condition c3 = lock.newCondition(); //创建condition对象
new Thread(new Runnable() {
public void run() {
lock.lock(); //加锁,
try {
c1.await(); //阻塞当前线程, 当signal的时候线程激活继续执行
Thread.sleep(1000);
System.out.println("粒粒皆辛苦");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); //解锁
}
}
}).start();
new Thread(new Runnable() {
public void run() {
lock.lock(); // 加锁
try {
c2.await(); // 阻塞当前线程, 当signal2的时候激活继续执行
Thread.sleep(1000);
System.out.println("谁知盘中餐");
c1.signal(); //激活t1线程
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 释放锁激活c1
}
}
}).start();
new Thread(new Runnable() {
public void run() {
lock.lock(); //加锁
try {
c3.await();// 阻塞当前线程, 当signal2的时候激活继续执行
Thread.sleep(1000);
System.out.println("汗滴禾下土");
c2.signal(); //激活t2线程
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); //释放锁 激活C2
}
}
}).start();
new Thread(new Runnable() {
public void run() {
lock.lock();
try {
Thread.sleep(1000);
System.out.println("锄禾日当午");
c3.signal(); //t3线程继续执行
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}).start();
}
}