概述
Condition接口提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式。
使用方法
Condition定义了等待/通知两种类型的方法,当前线程调用这些方法时,需要提前获取到Condition对象关联的锁。Condition对象是由Lock对象(调用Lock对象的newCondition()方法)创建出来的,换句话说,Condition是依赖Lock对象的。
/**
* 代码中的
* condition.await() 可以用 this.wait() 替代
* condition.signalAll() 可以用 this.notifyAll() 替代
*/
class Data {
private int num = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void increment() {
lock.lock();
try {
while (num != 0) {
condition.await();
}
num++;
System.out.println(Thread.currentThread().getName() + "=>" + num);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void decrement() {
lock.lock();
try {
while (num == 0) {
condition.await();
}
num--;
System.out.println(Thread.currentThread().getName() + "=>" + num);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
优点:精准的通知和唤醒线程
案例:按顺序打印出 A、B、C
/**
* Condition 精准的通知和唤醒线程!
*
* 案例:按顺序打印出 A、B、C
*
* 声明 num
* num = 1 时,打印 A
* num = 2 时,打印 B
* num = 3 时,打印 C
*
* 在 showA 中使num = 2 ,满足 showB 条件
* 在 showA 中使num = 3 ,满足 showC 条件
* 在 showA 中使num = 1 ,满足 showA 条件
* 以此来使其按照顺序打印
*
* @author dsstart
* @create 2020-12-02 15:12
*/
public class JUCVersion2 {
public static void main(String[] args) {
Data data = new Data();
new Thread(() -> {
for (int i = 0; i < 5; i++) {
data.showA();
}
}, "线程A:").start();
new Thread(() -> {
for (int i = 0; i < 5; i++) {
data.showB();
}
}, "线程B:").start();
new Thread(() -> {
for (int i = 0; i < 5; i++) {
data.showC();
}
}, "线程C:").start();
}
}
class Data {
private int num = 1;
private Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
private Condition conditionC = lock.newCondition();
public void showA() {
lock.lock();
try {
while (num != 1) {
conditionA.await();
}
num = 2;
System.out.println(Thread.currentThread().getName()+"=====A=====");
conditionB.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void showB() {
lock.lock();
try {
while (num != 2) {
conditionB.await();
}
num = 3;
System.out.println(Thread.currentThread().getName()+"=====B=====");
conditionC.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void showC() {
lock.lock();
try {
while (num != 3) {
conditionC.await();
}
num = 1;
System.out.println(Thread.currentThread().getName()+"=====C=====");
conditionA.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}