这两个方法不并在Thread类中,而是在Object类中.这说明任何对象均可以调用这两个方法.这两个方法的方法签名以下:java
public final void wait() throws InterruptedException; public final native void notify();
当一个对象实例调用了wait()方法后,当前线程就会在这个对象上等待.好比,线程A中,调用了OBJECT.wait()方法,那么A线程就暂停了执行,转为等待状态,它会一直等待到其余线程调用了同一对象OBJECT.notify()方法为止.这时,这个OBJECT对象就成为两个线程之间有效的通讯手段.ide
若是一个线程调用了OBJECT.wait(),那么它就会进入到一个线程等待的队列当中.这个等待队列当中,可能会有多个线程,由于系统多个线程都在同时等待某一个对象.当OBJECT.notify()被调用,JVM会从这个等待队列中,随机选择一个线程来唤醒.spa
要注意:上面的过程并非公平的,不会由于你的线程优先级高,或者先进入等待队列而被优先选择,是彻底随机的.线程
除了notify()方法外,Object类还有一个方法是:notifyAll()方法.它和notify()的用法基本一致,但不一样的是,它会唤醒线程等待队列中全部等待的线程,而不是随机选择一个.code
首先须要强调的是:这三个方法不是随便就能够调用的.它们必须包含在对应的synchronized语句块中,由于不管哪一个方法都要先得到同一个目标的监视器.对象
/** * <p>wait()和notify()方法案例</p> * <p> * wait()和notify()方法必须包含在对应的synchronized语句块当中, * 不管是wait()仍是notify都须要首先得到目标对象的一个监视器 * </p> * <p> * notify()和notifyAll()方法的区别在于: * <ul> * <li>notify():随机唤醒一个wait()的线程</li> * <li>notifyAll():唤醒所有wait()的线程</li> * </ul> * </p> * * <pre> * author XueQi * date 16/5/1 * </pre> */ public class SimpleWaitNotify { final static Object OBJECT = new Object(); public static class T1 implements Runnable { @Override public void run() { synchronized (OBJECT) { System.out.println(System.currentTimeMillis() + ":T1 start!"); try { System.out.println(System.currentTimeMillis() + ":T1 wait for object"); OBJECT.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis() + ":T1 end!"); } } } public static class T2 implements Runnable { @Override public void run() { synchronized (OBJECT) { System.out.println(System.currentTimeMillis() + ":T2 start!"); try { System.out.println(System.currentTimeMillis() + ":T2 wait for object"); OBJECT.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis() + ":T2 end!"); } } } public static class T3 implements Runnable { @Override public void run() { Thread.yield(); synchronized (OBJECT) { System.out.println(System.currentTimeMillis() + ":T3 start! notify one thread"); OBJECT.notify(); System.out.println(System.currentTimeMillis() + ":T3 end!"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static class T4 implements Runnable { @Override public void run() { Thread.yield(); synchronized (OBJECT) { System.out.println(System.currentTimeMillis() + ":T4 start! notify all thread"); OBJECT.notifyAll(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis() + ":T4 end!"); } } } public static void main(String[] args) { Thread t1 = new Thread(new T1()); Thread t2 = new Thread(new T2()); Thread t3 = new Thread(new T3()); Thread t4 = new Thread(new T4()); t1.start(); t2.start(); t3.start(); //t4.start(); } }
当咱们注释掉t4.start()时,执行main方法.咱们能够看到控制台只有一个线程end,另一个wait的线程因为监视器对象一直没有顺利得到.队列
当咱们注释掉t3.start(),执行main方法,能够看到全部wait的线程都被唤醒,并且是有顺序,不是同时被唤醒的.
it