在java SE5的java.util.concurrent类库中还有额外的显示工具可以用来重写
MaxOMatic.java
使用互斥并允许任务挂起的基本类是Condition,你可以通过在Condition上调用await()来挂起一个任务。当外部任务发生变化,意味着某个任务应该继续执行时,你可以通过调用signal()来通知这个任务,从而唤醒一个任务,或者调用signalAll()来唤醒所有在这个Condition()上被其自身挂起的任务(与使用notifyAll()相比,signalAll()是更安全的方式)。
class Car{
private Lock lock=new ReentrantLock();
private Condition condition=lock.newCondition();
private boolean waxOn=false;
public synchronized void waxed() {
waxOn=true;
condition.signalAll();
}
public synchronized void buffed() {
waxOn=false;
condition.signalAll();
}
public synchronized void waitingForWaxing() throws InterruptedException {
while(waxOn==false)
condition.await();
}
public synchronized void waitingForbBuffed() throws InterruptedException {
while(waxOn==true)
condition.await();
}
}
class WaxOn implements Runnable{
private Car car;
public WaxOn(Car car) {
this.car=car;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
while(!Thread.interrupted()) {
System.out.println("Wax On!");
TimeUnit.MILLISECONDS.sleep(200);
car.waxed();
car.waitingForbBuffed();
}
}catch(InterruptedException e) {
System.out.println("Exiting via interrupt");
}
System.out.println("Ending Wax On task");
}
}
class WaxOff implements Runnable{
private Car car;
public WaxOff(Car car) {
this.car=car;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
car.waitingForWaxing();
System.out.println("Wax Off!");
TimeUnit.MILLISECONDS.sleep(200);
car.buffed();
}catch(InterruptedException e) {
System.out.println("Exiting via interrupt");
}
System.out.println("Ending Wax Off task");
}
}
public class WaxOMatic {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
Car car=new Car();
ExecutorService exec=Executors.newCachedThreadPool();
exec.execute(new WaxOn(car));
exec.execute(new WaxOff(car));
TimeUnit.MILLISECONDS.sleep(5000);
exec.shutdownNow();
}
}
在Car的构造器中,单个的Lock将产生一个Condition对象,这个对象被用来管理任务间的通信。但是,这个Condition对象并不包含有关处理状态的信息,因此你需要管理额外的表示处理状态的信息,即boolean waxOn。
每个对Lock对象的调用都必须紧跟一个try-finally子句,用来保证在所有的情况下都能释放锁。 在使用内建版本时,任务在可以调用await(),signal()或signal()之前,必须拥有这个锁。