notify()和wait()

  

原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11398563.html

 

  notify() 和 wait() 主要是用来多个线程之间的协作。

  它们都是Object的方法,任何对象都可以调用这两个方法。

  首先设置一个多个线程共享的对象 :

 

//共享对象
Object shareObject = new Object();

 

  1.wait() :导致当前线程等待,直到另一个线程调用该对象的notify()或者notifyAll()方法;

  这里用代码解释一下:

class ThreadOne extends Thread{
        @Override
        public void run() {
            synchronized (shareObject){
                for (int i = 0; i < 10 ; i++){
                    System.out.println("A线程--->"+i);
                    shareObject.notify();
                    if (first){
                        first = false;
                        try {
                            shareObject.wait();
                        } catch (Exception e){
                            System.out.println(e);
                        }
                    }
                }
            }
        }
    }

  这里的 shareObject.wait(); 会导致ThreadOne线程进入shareObject对象的等待队列(这个等待队列可能会有多个线程,这些线程都停止继续执行,进入等待状态),直到其他线程调用shareObject的notify()或者notifyAll()方法,ThreadOne线程就可能会被唤醒,因为该唤醒是从等待队列中随机抽取一个线程进行唤醒,不公平唤醒。

  2.notify() :唤醒正在等待对象监视器的单个线程。这个在上面已经作了解释,下面用代码说明一下。

class ThreadTwo extends Thread{
        @Override
        public void run() {
            synchronized (shareObject){
                for (int i = 0; i < 10; i++){
                    System.out.println("B线程--->"+i);
                    shareObject.notify();
                    if (!first){
                        first = true;
                        try {
                            shareObject.wait();
                        }catch (Exception e){
                            System.out.println(e);
                        }
                    }
                }
            }
        }
    }

  这里的 shareObject.notify();会从shareObject对象的等待队列中随机唤醒一个线程,但是目前的shareObject对象的等待队列中只有ThreadOne一个线程,所以它就被唤醒了。

  过程如下图:

  

    最后:wait和sleep区别

  

    1️⃣ wait和sleep方法都可以让线程等待;


    2️⃣ wait()方法可以被唤醒,sleep不能被唤醒。


    3️⃣ wait()既会释放cpu,也会释放共享资源的锁,sleep()不会释放任何资源。


    4️⃣ wait和sleep方法都可以使线程进人阻塞状态。


    5️⃣ wait和sleep方法均是可中断方法,被中断后都会收到中断异常。


    6️⃣ wait是Object的方法,而sleep是Thread特有的方法。


    7️⃣ wait方法的执行必须在同步方法中进行,而sleep则不需要。


    8️⃣ 线程在同步方法中执行sleep方法时,并不会释放monitor的锁,而wait方法则会释放monitor的锁。


    9️⃣ sleep方法短暂休眠之后会主动退出阻塞,而wait方法(没有指定wait时间)则需要被其他线程中断后才能退出阻塞。

 

    🔟 sleep:是Thread的静态方法,会使当前线程释放cpu,但不会释放锁资源,可以理解为只和cpu有关,不涉及锁资源。涉及锁资源的,是wait,join方法。

 

    🔟1️⃣ yield:也是Thread的静态方法,和sleep方法类似,会使当前线程释放cpu,但不会释放锁资源。和sleep不同的是,sleep必须设置时间,但是yield不能设置时间,时间值是随机的

 

    🔟2️⃣ join: 等待join方法执行线程先执行完毕, main方法再继续执行; 例如 main方法中有一个线程thread执行了thread.join() ; 那么当main方法执行到了thread.join()语句时,必须等待thread线程执行完毕,才能继续执行;thread必须执行了start方法才会这样,如果没有执行start方法main方法会直接执行下去.

 

    结束🔚

posted @ 2019-08-23 10:35  前往幸福的路上  阅读(2617)  评论(0编辑  收藏  举报