Java 并发核心编程(五)

6、线程协作

6.1wait/notify

wait/notify关键字适用于一个线程通知另一个线程所需的条件状态已就绪,最常用于线程在循环中休眠直到获取特定条件的场景例如,一个线程一直等待直到队列中有一个组件能够处理;当组件添加到队列时,另一个线程能够通知这个等待的线程。

waitnotify的经典用法是:

 

Thread t = new Thread(runnable);

t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

public void uncaughtException(Thread t, Throwable    e) {

// TODO get Logger and log uncaught exception

}

});

t.start();

 

 

public class Latch {

private final Object lock = new Object();

private volatile boolean flag = false;

public void waitTillChange(){

synchronized (lock) {

while(!flag){

try {

lock.wait();

} catch (InterruptedException e) {

}

}

}

}

public void change(){

synchronized (lock) {

flag = true;

lock.notifyAll();

}

}

}

 

在代码中需要注意的重要地方是:

waitnotifynotifyAll必须在synchronized修饰的代码块中执行,否则会在运行的时候抛出IllegalMonitorStateException异常

在循环语句wait的时候一定要设定循环的条件--这样能够避免wait开始之前,线程所需的条件已经被其他线程提供了却依然开始此线程wait导致的时间消耗。同时,这种办法还能够保证你的代码不被虚假的信息唤醒。

总是要保证在调用notifynotifyAll之前,能够提供符合线程退出等待的条件。否则会出现即使线程接收到通知信息,却不能退出循环等待的情况。

6.2Condition

JavaSE5中新添加了java.util.concurrent.locks.Condition接口。Condition不仅在API中实现了wait/notify语义,而且提供了几个新的特性,例如:为每个Lock创建多重Condition、可中断的等待、访问统计信息等。Condition是通过Lock示例产生的,示例:

 

public class LatchCondition {

private final Lock lock = new ReentrantLock();

private final Condition condition = lock.newCondition();

private volatile boolean flag = false;

 

public void waitTillChange(){

lock.lock();

try{

while(!flag){

try {

condition.await();

} catch (InterruptedException e) {

}

}

}finally{

lock.unlock();

}

}

public void change(){

lock.lock();

try{

flag = true;

condition.notifyAll();

}finally{

lock.unlock();

}

}

}


 

你可能感兴趣的:(java,thread,编程)