代码示例:
package com.baidu.nuomi.concurrent; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.TimeUnit; /** * Created by sonofelice on 16/6/18. */ public class WaitNotify { static boolean flag = true; static Object lock = new Object(); public static void main(String[] args) throws Exception{ Thread waitThread = new Thread(new Wait(),"WaitThread"); waitThread.start(); TimeUnit.SECONDS.sleep(1); Thread notifyThread = new Thread(new Notify(),"NotifyThread"); notifyThread.start(); } static class Wait implements Runnable{ @Override public void run() { synchronized (lock){ while (flag){ try { System.out.println(Thread.currentThread() + " flag is true. wait @ " + new SimpleDateFormat("HH:mm:ss").format(new Date())); lock.wait(); }catch (InterruptedException e){ } } System.out.println(Thread.currentThread() + "flag is false. running @ " + new SimpleDateFormat("HH:mm:ss").format(new Date())); } } } static class Notify implements Runnable{ @Override public void run() { synchronized (lock){ System.out.println(Thread.currentThread() + "hold lock. notify @ " + new SimpleDateFormat("HH:mm:ss").format(new Date())); lock.notifyAll(); flag = false; SleepUtils.second(5); } synchronized (lock){ System.out.println(Thread.currentThread() + "hold lock again. sleep @ " + new SimpleDateFormat("HH:mm:ss").format(new Date())); SleepUtils.second(5); } } } }
输出如下:
Thread[WaitThread,5,main] flag is true. wait @ 12:21:04 Thread[NotifyThread,5,main]hold lock. notify @ 12:21:05 Thread[NotifyThread,5,main]hold lock again. sleep @ 12:21:10 Thread[WaitThread,5,main]flag is false. running @ 12:21:15 Process finished with exit code 0
调用wait() notify() notifyAll()方法时需要注意的细节:
1)使用wait() notify() notifyAll() 时需要先对调用对象加锁;
2)调用wait()方法后,线程状态由RUNNING 变为WAITING,并将当前线程放置到对象的等待队列。
3)notify()或notifyAll() 方法调用后,等待线程依旧不会从wait返回,需要调用notify()或notifyAll()的线程释放锁之后,等待线程才有机会从wait()返回。
4)notify()方法将等待队列中的一个等待线程从等待队列中移到同步队列中,而notifyAll()方法则是将等待队列中的所有的线程全部移到同步队列,被移动的线程状态由WAITING变为BLOCKED。
5)从wait()方法返回的前提是获得了调用对象的锁。
从上面的细节可以看出,等待/通知机制依托于同步机制,其目的就是确保等待线程从wait()方法返回时能够感知到通知线程对变量做出的修改。
从而抽象出等待/通知的经典范式:
等待方:
1)获取对象锁;
2)如果条件不满足,那么调用对象的wait()方法,被通知后仍要检查条件。
3)条件满足则执行对应的逻辑。
对应的伪代码如下:
synchronized(对象){
while(条件不满足){
Object.wait();
}
逻辑处理
}
通知方:
1)获得对象的锁;
2)改变条件;
3)通知所有等待在对象上的线程。
对应的伪代码如下:
synchronized(对象){
改变条件
对象.notifyAll();
}
时间: 2024-11-05 06:17:01