等待/通知的方法定义在所有对象的超类java.lang.Object上。
方法 | 描述 | |
---|---|---|
notify() | 通知一个在对象上等待的线程,使其从wait()方法返回,返回的前提是线程获取了对象的锁 | |
notifyAll() | 通知所有在该对象上等待的线程 | |
wait() | 调用该方法的线程进入WAITING状态,只有等待另外线程的通知或被中断才会返回,调用wait()方法会释放对象的锁 | |
wait(long) | 超时等待一段时间,毫秒为单位 | |
wait(long, int) | 对超时时间的细粒度控制 | ,可以达到纳秒 |
示例代码:
代码语言:javascript复制import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* @author pengjunzhe
*/
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();
}
public static class Wait implements Runnable {
@Override
public void run() {
// 加锁,获取lock对象的Monitor
synchronized (lock) {
// 条件不满足时,继续wait,同时释放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) {
e.printStackTrace();
}
}
// 条件满足时,完成工作
System.out.println(Thread.currentThread() " flag is false. running @ " new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
}
}
public static class Notify implements Runnable {
@Override
public void run() {
// 加锁,获取lock的Monitor
synchronized (lock) {
// 获取lock的锁,然后通知,通知时不释放lock的锁
// 直到当前线程释放了lock之后,WaitThread才从wait方法返回
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);
}
}
}
}
结果为:
代码语言:javascript复制Thread[WaitThread,5,main] flag is true. wait @ 15:05:55
Thread[NotifyThread,5,main] hold lock. notify @ 15:05:56
Thread[NotifyThread,5,main] hold lock again. sleep @ 15:06:01
Thread[WaitThread,5,main] flag is false. running @ 15:06:06
使用wait()、notify()以及notifyAll()时需要注意:
- 使用wait()、notify()以及notifyAll()需要先调用对象加锁
- 调用wait()方法后,线程状态由RUNNING变为WAITING,并将当前线程放置到对象的等待队列
- notify()方法或者notifyAll()方法调用后,等待线程不会从wait()返回,需要调用notify()方法或notifyAll()的线程释放锁后,等待线程才有机会从wait()返回
- 从wait()方法返回的前提是获得了调用对象的锁