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