wait¬ify
2016-07-06 本文已影响28人
全栈未遂工程师
等待/通知机制
方法名称 | 描述 |
---|---|
notify() |
通知一个在对象上等待的线程,使其从wait方法返回,而返回的前提示该线程获取到了对象的锁。调用notify并不会释放锁 |
notifyAll() |
通知所有等待在该对象上的线程 |
wait() |
调用该方法的线程进入WAITING状态,只有等待另外线程的通知或者被中断才会返回,需要注意,调用wait方法后,会释放对象锁 |
wait(long) |
超过等待一段时间,这里的参数时间是毫秒,也就是等待长达n毫秒,如果没有通知就超时返回 |
wait(long, int) |
对于超时时间更细粒度的控制,可以达到纳秒 |
package com.waitNotify;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
//wait、notify测试
public class WaitNotifyTest {
static boolean flag = true;
static Object lock = new Object();
public static void main(String[] args) {
Thread waitThread = new Thread(new Wait(), "waitThread");
waitThread.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread notifyThread = new Thread(new Notify(), "notifyThread");
notifyThread.start();
}
static class Wait implements Runnable{
public void run(){
//加锁
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()));
}
}
}
static class Notify implements Runnable{
public void run(){
//加锁
synchronized(lock){
//拥有了lock锁,进行通知,通知时不会释放lock锁
//只有当前线程释放了lock锁之后,wait线程才能从wait方法中返回
System.out.println(Thread.currentThread()+" hold lock.notify@" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
lock.notifyAll();
flag = false;
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//再次加锁
synchronized(lock){
System.out.println(Thread.currentThread()+" hold lock again.sleep@" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
输出结果:
Thread[waitThread,5,main] flag is true.wait@09:01:55
Thread[notifyThread,5,main] hold lock.notify@09:01:56
Thread[waitThread,5,main] flag is false.running@09:02:01
Thread[notifyThread,5,main] hold lock again.sleep@09:02:01
//注意:3、4行结果的输出顺序可能会调换。
注意:
- 使用
wait()
、notify()
、notifyAll()
时需要先对调用对象加锁。 - 调用wait之后,线程状态由RUNNING变为WAITING,并将当前线程放置到对象的等待队列。同时释放锁。
- notify或者notifyAll之后,等待线程依然不会从wait中返回,需要调用notify或notifyAll的线程释放锁之后,等待线程才有机会从wait中返回。
- notify方法将等待队列中的一个等待线程从等待队列中移到同步队列中,而notifyAll方法则是将等待队列中所有的线程移到同步队列中,所有被移动的线程状态从WAITING变成BLOCKED,然后各个线程竞争获得锁。
- 从wait方法返回的前提是获得了调用对象的锁。