Condition接口
任意一个Java对象,都拥有一组监视器方法(定义在java.lang.Object上),主要包括wait()、wait(long timeout)、notify()以及notifyAll()方法,这些方法与synchronized同步关键字配合,可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式。
Condition常用方法
方法名称 | 描述 |
void await() throws InterruptedException | 当前线程进入等待,知道被condition.signal()唤醒或者被中断 |
void awaitUninterruptibly() | 当前线程进入等待,能够响应中断 |
long awaitNanos(long nanosTimeout) thrwos InterruptedException | 1、返回0或者负数,表示超时了 2、正常被唤醒,返回剩余时间 |
boolean awaitUnitil(Date deadline) throws InterruptedException | 1、如果没有到指定时间就返回通知,返回true 2、倒了指定时间还没有被通知,返回false |
void signal() | 唤醒一个在condition.await()的程序 |
void signal() | 唤醒所有等待在condition上的现成 |
Condition使用格式
// 等待
lock.lock();
try {
condition.await();
} finally {
lock.unlock();
}
// 唤醒
lock.lock();
try {
condition.signalAll();
} finally {
lock.unlock();
}
备注:我一开始把condition.await();写成了condition.wait();,结果每次执行到这里的时候就会报错,以为是自己锁用错了,搞了半天才发现是少了个a,应该是await(),顿时心都碎了,特此记录,防止有人采坑
具体报错如下:
Exception in thread "Thread-5" java.lang.IllegalMonitorStateException
消费者消费了一个面包:9
消费者消费了一个面包:8
消费者消费了一个面包:7
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
消费者消费了一个面包:6
at cn.enjoyedu.ch4.TestCondition.product(TestCondition.java:24)
at cn.enjoyedu.ch4.TestCondition.lambda$main$1(TestCondition.java:61)
at java.lang.Thread.run(Thread.java:748)
示例:消费者生产者机制
public class TestCondition {
private int count = 0;
private static final int SUM = 10;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void product() {
while (true) {
lock.lock();
try {
while (count >= SUM) {
System.out.println("库存满了,等待消费" + count);
condition.await();
}
count++;
System.out.println("生产者生产了一个面包:" + count);
condition.signalAll();
} catch (InterruptedException e) {
//e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public void customer() {
while (true) {
lock.lock();
try {
while (count <= 0) {
System.out.println("库存为零,等待生产:" + count);
condition.await();
}
count--;
System.out.println("消费者消费了一个面包:" + count);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public static void main(String[] args){
TestCondition testCondition = new TestCondition();
for (int i = 0; i < 3; i++) {
new Thread(() -> testCondition.customer()).start();
new Thread(() -> testCondition.product()).start();
}
}
}
结果:
库存为零,等待生产:0
库存为零,等待生产:0
库存为零,等待生产:0
生产者生产了一个面包:1
生产者生产了一个面包:2
生产者生产了一个面包:3
生产者生产了一个面包:4
生产者生产了一个面包:5
生产者生产了一个面包:6
生产者生产了一个面包:7
生产者生产了一个面包:8
生产者生产了一个面包:9
生产者生产了一个面包:10
库存满了,等待消费10
库存满了,等待消费10
库存满了,等待消费10
消费者消费了一个面包:9
消费者消费了一个面包:8