關於thread.join()的一次錯誤理解

public static void main(String[] args) throws InterruptedException {

    Thread prevThread = Thread.currentThread();
    for(int i = 0;i<10;i++){
        Thread t = new Thread(new ThreadJoin(prevThread,i));
        t.start();
        prevThread = t;
    }

    TimeUnit.SECONDS.sleep(2);

    System.out.println(Thread.currentThread().getName()+"terminate");

}

private static class ThreadJoin implements Runnable{

    private Thread thread;

    private int num;

    public ThreadJoin(Thread thread, int num) {
        this.thread = thread;
        this.num = num;
    }

    public void run() {
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Thread name:"+Thread.currentThread().getName()+"***********"+num);
    }
}

一個簡單的例子,然後當時查看源碼,發現thread.join是鎖當前對象。

當時發現join鎖的是當前對象,而且進行了wait()方法,所以一直認爲是main線程.wait()進行無限期等待了,因爲一開始就是Main線程調用join()方法的,當時就一直想不通,main線程調用wait()方法把自己阻塞了,怎麼可能還能讓程序執行下去啊。一直沒法理解,然後又跑回去看wait()方法的介紹。發現object.wait()方法,需要當前線程持有object的鎖,就等於是synchronized的鎖對象是object,然後代碼裏object.wait(),這裏會使當前線程進行進入wait的等待對列,需要另外的線程調用notify或notifyAll方法,喚醒當前線程。所以前面示例代碼是thread0的線程調用main.join()。這裏的含義其實就是把main線程當成object對象,調用wait方法把當前線程thread0進入一個wait set隊列的waiting對列,但是main線程本身不受影響,繼續運行直至終結,但是JVM底層在線程執行完之後,會執行notifyAll來喚醒所有被自己阻塞進入waiting隊列的線程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章