java_66666 2018-07-12 02:37 采纳率: 0%
浏览 689
已结题

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

假设线程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的,难道不是随机的吗??

  • 写回答

4条回答 默认 最新

  • qq_38535182 2018-07-12 02:40
    关注

    这个我测试了一下
    把你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();
                }
            }
    

    图片说明

    评论
  • lawbc 2018-07-12 03:02
    关注

    这个要看cpu分配了,也要看线程的优先级

    评论
  • qq_42452306 2018-07-12 03:20
    关注

    理论上来说是cpu随机分配的,但是线程本身可以设置优先级,但优先级也只是更改概率罢了

    评论
  • 长河落雨 2018-07-12 06:13
    关注

    按照Think in Java中的解释:"wait()允许我们将线程置入“睡眠”状态,同时又“积极”地等待条件发生改变.而且只有在一个notify()或notifyAll()发生变化的时候,线程才会被唤醒,并检查条件是否有变."
    先wait的线程优先

    评论

报告相同问题?

悬赏问题

  • ¥15 activity升级到flowable工作流act_ge_bytearray的草稿json数据复制到act_de_model 的model_editor_json的脚本
  • ¥15 cvi使用CreateThread创建线程时,出现存储空间不足无法处理此命令的错误
  • ¥15 求苹果推信imessage批量推信技术
  • ¥15 ubuntu 22.04 系统盘空间不足。隐藏的docker空间占用?(相关搜索:移动硬盘|管理系统)
  • ¥15 c++ word自动化,为什么可用接口是空的?
  • ¥15 Matlab计算100000*100000的矩阵运算问题:
  • ¥50 VB6.0如何识别粘连的不规则的数字图片验证码
  • ¥16 需要完整的这份订单所有的代码,可以加钱
  • ¥30 写一个带界面控制的机房电脑一键开机关机并且实时监控的软件
  • ¥15 Stata数据分析请教