zoukankan      html  css  js  c++  java
  • notify()和notifyAll()有什么区别?

    先解释两个概念。

    • 等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池,等待池中的线程不会去竞争该对象的锁。
    • 锁池:只有获取了对象的锁,线程才能执行对象的 synchronized 代码,对象的锁每次只有一个线程可以获得,其他线程只能在锁池中等待


    区别:

    notify() 方法随机唤醒对象的等待池中的一个线程,进入锁池;notifyAll() 唤醒对象的等待池中的所有线程,进入锁池。

    测试代码

    public class TestNotifyNotifyAll {
     
        private static Object obj = new Object();
        
        public static void main(String[] args) {
            
            //测试 RunnableImplA wait()        
            Thread t1 = new Thread(new RunnableImplA(obj));
            Thread t2 = new Thread(new RunnableImplA(obj));
            t1.start();
            t2.start();
            
            //RunnableImplB notify()
            Thread t3 = new Thread(new RunnableImplB(obj));
            t3.start();
            
            
    //        //RunnableImplC notifyAll()
    //        Thread t4 = new Thread(new RunnableImplC(obj));
    //        t4.start();
        }
        
    }
     
     
    class RunnableImplA implements Runnable {
     
        private Object obj;
        
        public RunnableImplA(Object obj) {
            this.obj = obj;
        }
        
        public void run() {
            System.out.println("run on RunnableImplA");
            synchronized (obj) {
                System.out.println("obj to wait on RunnableImplA");
                try {
                    obj.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("obj continue to run on RunnableImplA");
            }
        }
    }
     
    class RunnableImplB implements Runnable {
     
        private Object obj;
        
        public RunnableImplB(Object obj) {
            this.obj = obj;
        }
        
        public void run() {
            System.out.println("run on RunnableImplB");
            System.out.println("睡眠3秒...");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (obj) {
                System.out.println("notify obj on RunnableImplB");
                obj.notify();
            }
        }
    }
     
    class RunnableImplC implements Runnable {
     
        private Object obj;
        
        public RunnableImplC(Object obj) {
            this.obj = obj;
        }
        
        public void run() {
            System.out.println("run on RunnableImplC");
            System.out.println("睡眠3秒...");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (obj) {
                System.out.println("notifyAll obj on RunnableImplC");
                obj.notifyAll();
            }
        }
    }

    结果:仅调用一次 obj.notify(),线程 t1 或 t2 中的一个始终在等待被唤醒,程序不终止

    run on RunnableImplA
    obj to wait on RunnableImplA
    run on RunnableImplA
    obj to wait on RunnableImplA
    run on RunnableImplB
    睡眠3秒...
    notify obj on RunnableImplB
    obj continue to run on RunnableImplA

     把 t3 注掉,启动 t4 线程。调用 obj.notifyAll() 方法

    public class TestNotifyNotifyAll {
     
        private static Object obj = new Object();
        
        public static void main(String[] args) {
            
            //测试 RunnableImplA wait()        
            Thread t1 = new Thread(new RunnableImplA(obj));
            Thread t2 = new Thread(new RunnableImplA(obj));
            t1.start();
            t2.start();
            
    //        //RunnableImplB notify()
    //        Thread t3 = new Thread(new RunnableImplB(obj));
    //        t3.start();
            
            
            //RunnableImplC notifyAll()
            Thread t4 = new Thread(new RunnableImplC(obj));
            t4.start();
        }
        
    }

     结果:t1、t2线程均可以执行完毕

    run on RunnableImplA
    obj to wait on RunnableImplA
    run on RunnableImplA
    obj to wait on RunnableImplA
    run on RunnableImplC
    睡眠3秒...
    notifyAll obj on RunnableImplC
    obj continue to run on RunnableImplA
    obj continue to run on RunnableImplA


    原文链接
     


     

    所有资源资源汇总于公众号



     

  • 相关阅读:
    JavaScript中的数据类型转换
    JavaScript中的变量
    set_uid set_gid stick_bit 软硬链接
    chmod、chown、umask、lsattr/chattr
    环境变量、cp、mv、cat 等命令
    相对和绝对路径 mkdir cd rm 等命令
    linux 系统 目录,以部分及相关命令
    单用户模式 和救援模式 、以及相互登陆(免密)
    putty 、xshell的使用 和 putty 、xshell、 shell 间免密登陆
    vmware NAT 网络出现问题的解决方法
  • 原文地址:https://www.cnblogs.com/ConstXiong/p/12009144.html
Copyright © 2011-2022 走看看