引言
当我们使用线程来同时运行多个任务时,可以通过使用锁来同步两个任务的行为,从而使得一个任务不会干涉另一个任务的资源。
对此 java提供了原生的wait(),notifyAll()这组唤醒与等待的机制
唤醒等待实践
这里要注意的一个点是 sleep() 与wait()主要的区别是,sleep的时候锁没有释放,yield() 也是,但是调用wait()会释放锁,线程将被挂起 直到接收到nofity(), notifyAll()消息
简单看个示例
CarWorker.java有两个过程 一个是将蜡涂到Car上,一个是抛光它。抛光任务在涂蜡任务完成之前是不能执行其工作的。WaxOn,WaxOff 都使用率额 Car对象,该对象在这些任务等待条件变化的时候 使用wait() 和 notifyAll()来挂起和重新启动这些任务。
下面看代码
Car.java
public class Car {
private boolean waxOn = false;
public synchronized void waxed() {
waxOn = true;
notifyAll();
}
public synchronized void buffed() {
waxOn = false;
notifyAll();
}
public synchronized void waitForWaxing()
throws InterruptedException{
while (!waxOn)
wait();
}
public synchronized void waitForBuffing()
throws InterruptedException{
while (waxOn)
wait();
}
}
WaxOn.java
public class WaxOn implements Runnable {
private Car car;
public WaxOn(Car car) {
this.car = car;
}
@Override
public void run() {
while (!Thread.interrupted()) {
try {
car.waitForBuffing();
System.out.print("wax on! ");
TimeUnit.MICROSECONDS.sleep(200);
car.waxed();
} catch (InterruptedException e) {
System.out.println("Exiting via interrupt");
}
}
System.out.println("Ending Wax On task!");
}
}
WaxOff.java
public class WaxOff implements Runnable {
private Car car;
public WaxOff(Car car) {
this.car = car;
}
@Override
public void run() {
while (!Thread.interrupted()) {
try {
car.waitForWaxing();
System.out.print("Wax off!");
TimeUnit.MICROSECONDS.sleep(200);
car.buffed();
} catch (InterruptedException e) {
System.out.println("WaxOff interrupted");
}
}
System.out.println("ending Wax Off task! ");
}
}
启动类 CarWorker.java
public class CarWorker {
public static void main(String[] args) throws InterruptedException {
Car car = new Car();
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(new WaxOff(car));
executor.execute(new WaxOn(car));
TimeUnit.SECONDS.sleep(5);
executor.shutdownNow();
}
}
waitForWaxing中将坚持waxOn标志 如果它为false,那么这个调用任务通过调用wait()而被挂起
运行结果如下: on-off有序的交替执行