zoukankan      html  css  js  c++  java
  • notify和notifyAll的区别

    1、我们先验证下wait可以用notify和notifyAll来唤醒

    如下测试代码:

    public class WaitSleepDemo {
    
        public static void main(String[] args) {
            final  Object lock = new Object();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("thread A is waiting to get lock");
                    synchronized (lock){
    
                        try {
                            System.out.println("thread A get lock");
                            Thread.sleep(20);
                            System.out.println("thread A do wait method");
                            //无限期的等待
                            lock.wait();
                            //Thread.sleep(1000);
                            System.out.println("thread A is done");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
    
    
            //为了让Thread A 先于Thread B执行
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("thread B is waiting to get lock");
                    synchronized (lock){
                        try {
                            System.out.println("thread B get lock");
                            System.out.println("thread B is sleeping 10 ms");
                           Thread.sleep(10);
                           // lock.wait(10);
                            System.out.println("thread B is done");
                            //这句注释掉,thread A is done就不会被打印
                            lock.notify(); // lock.notifyAll();
                           
    
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    
                    }
                }
            }).start();
        }
    }
    

      

      执行结果:

    thread A is waiting to get lock
    thread A get lock
    thread B is waiting to get lock
    thread A do wait method
    thread B get lock
    thread B is sleeping 10 ms
    thread B is done
    thread A is done
    

      

    2、notify和notifAll的区别

    两个概念

    锁池EntryList

    等待池 WaitSet

    锁池:

    假设线程A已经拥有了某个对象(不是类)的锁,而其它线程B,C想要调用这个对象的某个某个synchronized方法(或者块)之前必须获得该对象锁的拥有权,而恰巧该对象的锁目前正被A所占有,此时B, C线程就会被阻塞,进入一个地方去等待锁的释放,这个地方便是该对象的锁池。

    等待池

       假设线程A调用了某个对象的wait方法,线程A就会释放该对象的锁,同时线程A就进入到了该对象的等待池中,进入等待池中的线程不会去竞争该对象的锁。

     notify和notifAll的区别

    notifyAll: 会让所有处于等待池的线程全部进入锁池去竞争获取锁的机会

    notify: 只会随机选取一个处于等待池中的线程进入锁池去竞争获取锁的机会。

    如下的测试代码

    public class NotificationDemo {
        private volatile boolean go = false;
    
    
        private synchronized  void shouldGo() throws InterruptedException {
    
            while (go != true){
                System.out.println(Thread.currentThread() + " is going to wait on this object");
                wait();
                System.out.println(Thread.currentThread() + " is woken up");
    
            }
            go = false; //reseting condition
        }
    
    
        private synchronized  void go() throws InterruptedException {
    
            while (go == false){
                System.out.println(Thread.currentThread() + " is going to notify all or one ");
                go = true;
    
                notify();
            }
    
        }
    
    
    
        public static void main(String[] args) throws InterruptedException {
    
            NotificationDemo test = new NotificationDemo();
    
              Runnable waitTak = new Runnable() {
                @Override
                public void run() {
                    try {
                        test.shouldGo();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " finish execution");
                }
            };
    
             Runnable notifyTask = new Runnable() {
                @Override
                public void run() {
                    try {
                        test.go();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " finish execution");
                }
            };
    
            Thread t1 = new Thread(waitTak, "WT1");
            Thread t2 = new Thread(waitTak, "WT2");
            Thread t3 = new Thread(waitTak, "WT3");
            t1.start();
            t2.start();
            t3.start();
    
            Thread t4 = new Thread(notifyTask, "NT1");
            Thread.sleep(200);
            t4.start();
    
    
        }
    }
    

      打印结果:

    Thread[WT1,5,main] is going to wait on this object
    Thread[WT2,5,main] is going to wait on this object
    Thread[WT3,5,main] is going to wait on this object
    Thread[NT1,5,main] is going to notify all or one 
    Thread[WT1,5,main] is woken up
    NT1 finish execution
    WT1 finish execution
    

      多执行几次,可以发现notify调用后,被唤醒的线程是随机的。

    将notify改成notifyAll

     打印结果如下:

    Thread[WT1,5,main] is going to wait on this object
    Thread[WT3,5,main] is going to wait on this object
    Thread[WT2,5,main] is going to wait on this object
    Thread[NT1,5,main] is going to notify all or one 
    Thread[WT2,5,main] is woken up
    Thread[WT3,5,main] is woken up
    Thread[WT3,5,main] is going to wait on this object
    NT1 finish execution
    Thread[WT1,5,main] is woken up
    Thread[WT1,5,main] is going to wait on this object
    WT2 finish execution
    

      说明三个线程都被唤醒了

  • 相关阅读:
    搜狗输入法赏析
    第二次冲刺个人总结05
    程序员的自我修养阅读笔记01
    第十五周学习总结
    mysql 查询优化
    mysql explain 详解
    nginx基本配置与参数说明
    input输入框实现联想关键词功能
    JS图片懒加载
    mysql中timestamp,datetime,int类型的区别与优劣
  • 原文地址:https://www.cnblogs.com/linlf03/p/12113185.html
Copyright © 2011-2022 走看看