在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()之前,必須擁有這個鎖。