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

2020-08-28 22:49:09 +08:00
 Newyorkcity
    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();
                }
            }
        }
    }

谢谢

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

如果 dosomething 会产生 io 或其它阻塞, 需要获取第二个锁才能往下执行, 则两者是有区别的, 除了 sleep, dosomething 在因锁阻塞的时候会释放所有之前所得到的锁, 对于前者而言, 因为 notify 已经调用, 之前处于 wait 的线程会被唤醒执行, 而后者不会唤醒

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/702315

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX