除了Object对象提供了wait(),notify()以及notifyAll()这些方法对java对象进行监视之外,Condition接口也提供了与Object相似的监视器方法,在获取到Lock对象之后,配合Condition 提供的方法,也能进行线程间的协作。使用Condition必须先获取锁,比如可以这样获取一个可重入锁 :Lock lock = new ReentrantLock(); 再由Lock对象的 newCondition()方法得到一个Condition对象:Condition condition = lock.newCondition();Condition提供的 await()方法可以让线程进入等待状态,其他线程可以调用signal()或signalAll()将等待的线程唤醒。
以下是用Condition监视器代替Object的监视器的例子
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestSignalAll {
public static void main(String[] args) throws InterruptedException {
Product product = new Product();
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(new Processer(product));
executor.execute(new Producer(product));
}
}
class Product{
private Lock lock = new ReentrantLock();//创建一个重入所
private Condition condition = lock.newCondition();
private boolean produce = false;//默认生产的机器是为完成生产动作的
public void produce(){
lock.lock();
try{
produce = true;//开始生产
condition.signalAll();
}finally{//保证在任何情况下都会释放锁,以下都有这个动作
lock.unlock();
}
}
public void process(){
lock.lock();
try{
produce = false;
condition.signalAll();
}finally{
lock.unlock();
}
}
public void waitForProduce() throws InterruptedException{
lock.lock();
try{
while(produce==false){
condition.await();
}
}finally{
lock.unlock();
}
}
public void waitForProcess() throws InterruptedException{
lock.lock();
try{
while(produce==true){
condition.await();
}
}finally{
lock.unlock();
}
}
}
class Producer implements Runnable{
private Product product;
public Producer(Product p){product = p;}
@Override
public void run() {
while(!Thread.interrupted()){
System.out.println("生产一个未加工产品+++");
try {
TimeUnit.SECONDS.sleep(1);//模拟一个加工过程,5秒之后代表有个未加工的产品生成
product.produce();//通知所有等待的线程准备获取检查条件,获取控制权,此时produce=true;
product.waitForProcess();//上一步 produce=true ,到这里因为条件满足,所有进入等待,移交出控制权。
} catch (InterruptedException e) {
System.out.println("中断退出");
}
}
}
}
class Processer implements Runnable{
private Product product;
public Processer(Product p){product = p;}
@Override
public void run() {
while(!Thread.interrupted()){
try {
product.waitForProduce();//如果 produce 为false则一直在等待,以下动作不会执行
System.out.println("处理一个产品---");//执行到这里,说明没有进入waitForProduce的等待 ,此时produce 为true
TimeUnit.SECONDS.sleep(1);
product.process();//设置produce为false,这个条件会让product.waitForProduce()进入等待状态,同时通知所有等待的线程。
} catch (InterruptedException e) {
System.out.println("中断退出");
}
}
}
}
执行结果跟采用Object的notifyAll()是一样的:
生产一个未加工产品+++
处理一个产品---
生产一个未加工产品+++
处理一个产品---
生产一个未加工产品+++
处理一个产品---
生产一个未加工产品+++
处理一个产品---
......