wait() notify() notifyAll()小结

1.wait()和notify()是如何工做的?

    这两个方法不并在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

    要注意:上面的过程并非公平的,不会由于你的线程优先级高,或者先进入等待队列而被优先选择,是彻底随机的.线程


2.notify()和notifyAll()的区别

    除了notify()方法外,Object类还有一个方法是:notifyAll()方法.它和notify()的用法基本一致,但不一样的是,它会唤醒线程等待队列中全部等待的线程,而不是随机选择一个.code


3.wait() notify() notifyAll()的使用方法

    首先须要强调的是:这三个方法不是随便就能够调用的.它们必须包含在对应的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

相关文章
相关标签/搜索