鍍金池/ 問答/Java  C  Linux  網絡安全/ 線程競爭資源時候有沒有先后順序

線程競爭資源時候有沒有先后順序

假設線程1執(zhí)行了wait(),線程2獲取到了鎖資源,與此同時線程3啟動執(zhí)行synchronized競爭鎖資源,線程2在結束之前使用了notifyAll()喚醒線程1,那么線程1和線程3誰能獲取到鎖是隨機的嗎?
在我的理解中,是隨機的,但是現在的實際情況是線程1會獲取到資源
請問是我理解錯了嗎,請說明一下。

還有就是線程1執(zhí)行了wait之后,線程4先獲取到鎖資源,但是也執(zhí)行了wait,然后按照上面的繼續(xù)進行下去的,在線程2結束的時候,為什么會執(zhí)行線程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釋放的,一定會是第一個執(zhí)行wait的,難道不是隨機的嗎??

回答
編輯回答
舊城人

我在stackoverflow上找到了答案,各位感興趣可以看一下
https://stackoverflow.com/que...

2017年8月13日 09:31
編輯回答
寫榮

這個我測試了一下
把你co.notify()改成notifyAll(),結果每次都是Thread-0被首先喚醒,然后其他是隨機的。
目前我只能認為是編譯器的優(yōu)化。
想達到隨機喚醒,來 一睡解千愁

        @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

2017年2月14日 12:39