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隊列的線程。