V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Newyorkcity
V2EX  ›  问与答

Java 中 notify()在最开始和在最后没有区别吗?

  •  
  •   Newyorkcity · 2020-08-28 22:49:09 +08:00 · 535 次点击
    这是一个创建于 422 天前的主题,其中的信息可能已经有所发展或是发生改变。
        public static class Task implements Runnable {
    
            private static final Object lock = new Object();
    
            @Override
            public void run() {
                synchronized (lock) {
                    if (...){
                        lock.notify();
                        dosomething();
                    }
                }
            }
        }
    
    

    这两者的结果是一样的,在任何情况下?

        public static class Task implements Runnable {
    
            private static final Object lock = new Object();
    
            @Override
            public void run() {
                synchronized (lock) {
                    if (...){
                        dosomething();
                        lock.notify();
                    }
                }
            }
        }
    
    

    谢谢

    3 条回复    2020-08-29 15:48:35 +08:00
    Godjack
        1
    Godjack   2020-08-29 09:37:16 +08:00 via Android   ❤️ 1
    notify 会使 wait 的线程被唤醒,因为被唤醒的线程需要等到 notify 所在的同步代码块结束后才能获得锁,为了 wait 线程避免被唤醒但拿不到锁而引起的线程阻塞,最好把 notify 写在靠近同步代码块结束的位置。
    Godjack
        2
    Godjack   2020-08-29 09:39:19 +08:00 via Android   ❤️ 1
    为了避免 wait 线程被唤醒但拿不到锁而引起的线程阻塞
    SoloCompany
        3
    SoloCompany   2020-08-29 15:48:35 +08:00   ❤️ 1
    只有在 dosomething 是运算密集中间没有任何地方会进入等待状态的时候, 两者才是等价的

    如果 dosomething 会产生 io 或其它阻塞, 需要获取第二个锁才能往下执行, 则两者是有区别的, 除了 sleep, dosomething 在因锁阻塞的时候会释放所有之前所得到的锁, 对于前者而言, 因为 notify 已经调用, 之前处于 wait 的线程会被唤醒执行, 而后者不会唤醒
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2617 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 14:46 · PVG 22:46 · LAX 07:46 · JFK 10:46
    ♥ Do have faith in what you're doing.