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()方法返回的前提是获得了调用对象的锁。
public class NotifyWait {
static boolean flag = true;
static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread waitThread = new Thread(new Wait());
waitThread.start();
TimeUnit.SECONDS.sleep(1);
Thread notifyThread = new Thread(new Notify());
notifyThread.start();
}
static class Wait implements Runnable {
@Override
public void run() {
synchronized (lock) {
while (flag) {
try {
System.out.println(Thread.currentThread() + ":flag true");
lock.wait();
} catch (InterruptedException e) {
}
}
System.out.println(Thread.currentThread() + ":flag false");
}
}
}
static class Notify implements Runnable {
@Override
public void run() {
synchronized (lock) {
System.out.println(Thread.currentThread() + "hold");
lock.notifyAll();
flag = false;
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
}
synchronized (lock) {
System.out.println(Thread.currentThread() + "hold again");
}
}
}
}
Thread[Thread-0,5,main]:flag true
Thread[Thread-1,5,main]hold
Thread[Thread-1,5,main]hold again
Thread[Thread-0,5,main]:flag false
经典范式
等待方:
synchronized (对象){
while(条件不满足){
对象.wait();
}
对应处理
}
通知方:
synchronized (对象){
改变条件
对象.notifyAll();
}