线程间的通信----wait/notify机制
wait/notify机制
实现多个线程之间的通信可以使用wait、notify、notifyAll三个方法。这三个方法都是Object类的方法。
wait():导致当前线程等待,直到另一个线程调用此对象的 notify()方法或 notifyAll()方法。
wait(long timeout):导致当前线程等待,直到另一个线程调用此对象的 notify()方法或 notifyAll()方法,或者已经过了指定的时间量。
notify():唤醒正在此对象监视器上等待的单个线程。
notifyAll():唤醒等待此对象监视器的所有线程。
在调用以上方法时必须获得对象的对象锁,要在同步方法,或者同步块中调用。否则会抛出IllegalMonitorStateException。
wait执行后锁被自动释放,notify执行后并不会立即释放此对象的锁,需要等到notify的synchronized方法执行完全后,wait的线程才能获得对象锁。
验证代码
等待线程:
/** * @author monkjavaer * @date 2018/12/13 22:00 */ public class ThreadWait extends Thread { private Object work; public ThreadWait(Object work) { this.work = work; } @Override public void run() { try { synchronized (work){ System.out.println("...before wait..."); work.wait(); System.out.println("...after wait..."); } } catch (InterruptedException e) { e.printStackTrace(); } } }
唤醒线程:
/** * @author monkjavaer * @date 2018/12/13 22:04 */ public class ThreadNotify extends Thread { private Object work; public ThreadNotify(Object work) { this.work = work; } @Override public void run() { synchronized (work){ System.out.println("...before notify..."); work.notify(); System.out.println("...after notify..."); //此处可测试,notify执行后并没有释放此对象的锁,需要等到notify的synchronized方法执行完全后,wait的线程才能获得对象锁。 try { TimeUnit.MILLISECONDS.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("...after notify synchronized..."); } }
测试:
public class WaitNotifyTest { public static void main(String[] args) { Object work = new Object(); ThreadWait wait = new ThreadWait(work); wait.start(); ThreadNotify notify = new ThreadNotify(work); notify.start(); } }
输出:
...before wait... ...before notify... ...after notify... ...after notify synchronized... ...after wait...