线程竞争资源时候有没有先后顺序

发布于 2022-09-07 16:42:56 字数 1603 浏览 16 评论 0

假设线程1执行了wait(),线程2获取到了锁资源,与此同时线程3启动执行synchronized竞争锁资源,线程2在结束之前使用了notifyAll()唤醒线程1,那么线程1和线程3谁能获取到锁是随机的吗?
在我的理解中,是随机的,但是现在的实际情况是线程1会获取到资源
请问是我理解错了吗,请说明一下。

还有就是线程1执行了wait之后,线程4先获取到锁资源,但是也执行了wait,然后按照上面的继续进行下去的,在线程2结束的时候,为什么会执行线程1和线程4。

public class ThreadTest {
    public static void main(String[] args) {
        Object co = new Object();
        System.out.println(co);

        for (int i = 0; i < 10; i++) {
            MyThread t = new MyThread("Thread" + i, co);
            t.start();
        }

        try {
            TimeUnit.SECONDS.sleep(2);
            System.out.println("-----Main Thread notify-----");
            synchronized (co) {
                co.notify();
            }
            TimeUnit.SECONDS.sleep(2);
            System.out.println("Main Thread is end.");

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static class MyThread extends Thread {
        private String name;
        private Object co;

        public MyThread(String name, Object o) {
            this.name = name;
            this.co = o;
        }

        @Override
        public void run() {
            System.out.println(name + " is waiting.");
            try {
                synchronized (co) {
                    co.wait();
                }
                System.out.println(name + " has been notified.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

比如说这个代码,先不管他会造成死锁,问题是main中那个notify释放的,一定会是第一个执行wait的,难道不是随机的吗??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黯然 2022-09-14 16:42:56

这个我测试了一下
把你co.notify()改成notifyAll(),结果每次都是Thread-0被首先唤醒,然后其他是随机的。
目前我只能认为是编译器的优化。
想达到随机唤醒,来 一睡解千愁

        @Override
        public void run() {
            System.out.println(name + " is waiting. theThreadName :"+Thread.currentThread().getName());
            try {
                Thread.currentThread().sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                synchronized (co) {
                    co.wait();
                }
                System.out.println(name + " has been notified theThreadName :"+Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

clipboard.png

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文