一,Condition的作用與Object.wait(),Object.notify()的作用相似
1,Condition是一個藉口,提供了幾個常用的方法。
void await() throws InterruptedException;使當前線程進入等待狀態,同時釋放鎖。與Object的wait()方法相似
void awaitUninterruptibly();和上一個相似,但是不會在等待過程中相應中斷
void signal();與Object.notify()相似
void signalAll();這兩個都是喚醒處於等待的線程,與Object.notifyAll()相似
2,Condition對象是由ReentrandLcok的類似工廠方法返回 一個ConditionObejct,該對象的構造方法由AQS提供。
二,使用Condition的方法來實現單一消費者生產者模式
package Akka構建高併發程序;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 通知等待機制 實現消費者者/生產者模式
*/
public class PCDemo {
//消費品
public static class Data{
public static String value = " ";
}
//使用一把把公共重入鎖
public static Lock lock = new ReentrantLock();
//使用lock 返回Condition對象
public static Condition condition = lock.newCondition();
//生產者
public static class Producer{
public void setValue() throws Exception{
try {
lock.lock();
if (!Data.value.equals(" ")){ //說明value沒有被消費
condition.await();
}else{
String s = System.currentTimeMillis()+" ";
System.out.println("設置的value = " + s+" 當前線程的Name = "+Thread.currentThread().getName());
Data.value = s;//生產數據
condition.signal();//通知等待的消費者去消費
}
} finally {
lock.unlock();
}
}
}
//消費者
public static class Consumer{
public void getValue() throws Exception{
try {
lock.lock();
if (Data.value.equals(" ")){ //說明生產者沒有生產數據
condition.await();//消費者等待
}else {
System.out.println("消費者獲得的值 "+ Data.value+" 當前線程的Name = "+Thread.currentThread().getName());
Data.value = " ";//模擬把數據消費了
condition.signal();//通知生產者趕快生產數據 ,我已經消費完了
}
} finally {
lock.unlock();
}
}
}
//生產者線程
public static class ProThread implements Runnable{
private Producer producer;
public ProThread(Producer p){
this.producer = p;
}
@Override
public void run() {
while (true){
try {
producer.setValue();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
//消費者線程
public static class ConThread implements Runnable{
private Consumer consumer;
public ConThread(Consumer consumer){
this.consumer = consumer;
}
@Override
public void run() {
try {
while (true){
consumer.getValue();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception{
Thread p = new Thread(new ProThread(new Producer()));
Thread c = new Thread(new ConThread(new Consumer()));
p.setName("Producer");
c.setName("Consumer");
p.start();
c.start();
}
}
運行結果與使用Object的方法一樣,
如果要通知多個線程,把signal()改爲signalAll()就好了,
參考:《Java高併發程序設計》