这节课我们来填坑,讲讲wait,notify,notifyAll,这三个方法主要用于线程间通信。

 

  先来看API文档怎么写的:

线程第九课——线程通信_数据结构与算法

线程第九课——线程通信_Java学习_02 

线程第九课——线程通信_数据结构与算法_03 

 

看到这里的人先暂停一下,把上面的截图过一遍。

 

下面来讲讲怎么用:

Demo:

/**

 * 线程间通信教学

 */

public class ThreadCommunicationTeach {



    public static void main(String[] args) throws InterruptedException {



        //纯粹的监视器

        //一个监视器可以监视多个线程,但是一个线程在同一时间只能有一个监视器

        Object listener = new Object();



        Thread thread1 = new MyThread2(listener,"线程1");

        Thread thread2 = new MyThread2(listener,"线程2");



        thread1.start();

        thread2.start();



        while (true)

        {

            if (thread1.getState() == Thread.State.WAITING)

            {

                System.out.println("线程1进入阻塞状态");

                Thread.sleep(1000);

                //这里没加同步

                synchronized (listener)

                {

                    listener.notify();

                }



            }

            if (thread2.getState() == Thread.State.WAITING)

            {

                System.out.println("线程2进入阻塞状态");

                Thread.sleep(1000);

                synchronized (listener)

                {

                    listener.notify();

                }

            }

            if (thread1.getState() == Thread.State.TERMINATED && thread2.getState() == Thread.State.TERMINATED)

            {

                break;

            }



        }



        /**

         * 可以看到抛出异常了: IllegalMonitorStateException

         *

         * 通过以下三种方法之一,线程可以成为此对象监视器的所有者:

         *

         * 通过执行此对象的同步实例方法。

         * 通过执行在此对象上进行同步的 synchronized 语句的正文。

         * 对于 Class 类型的对象,可以通过执行该类的同步静态方法。

         *

         * 说白了就是要加synchronized

         * wait和notify以及notifyAll三个方法都必须在同步方法或者同步方法块里

         * 否则抛异常IllegalMonitorStateException

         *

         * 如何保证多线程有序执行?就是用线程间通信。

         *

         * 接下来说说wait

         * wait就是让当前正在运行的线程进入等待状态,并且调用wait方法的对象会成为这个等待线程的监视器

         * 一个监视器可以监视多个线程,但一个线程同一时间只能有一个监视器

         *

         * notify:

         * 调用此方法的对象唤醒该对象所监视的所有线程中的一个(随机的)

         * 唤醒的意思就是让处于等待状态的线程进入就绪状态

         *
         * notifyAll:

         * 调用此方法的对象唤醒该对象所监视的所有线程

         */

    }

}



//瞎取个名字

class MyThread2 extends Thread{



    //监视器,用于让本线程进入等待状态(也叫阻塞状态)或唤醒该线程

    Object listener;



    public MyThread2(Object listener,String name)

    {

        this.listener = listener;

        setName(name);

    }



    @Override

    public void run() {

        for (int i = 0; i < 5; i++) {

            if (i == 2)

            {

                try {

                   synchronized (listener)

                   {

                       listener.wait();

                   }

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

            //这个居然忘记加了,要看下怎么输出的对吧

            System.out.println(getName() + ": " + i);

        }

    }

}