1. 程式人生 > >《多執行緒程式設計》學習之八:方法join()的使用、類ThreadLocal的使用

《多執行緒程式設計》學習之八:方法join()的使用、類ThreadLocal的使用

一、join()方法的使用

        一般主執行緒用於建立與啟動子執行緒,如果子執行緒的run()方法耗時比較長,主執行緒常先於子執行緒結束。如果需要主執行緒等待子執行緒執行完畢後再結束,就要用到join()方法。

1.1)子執行緒執行時間不確定,主執行緒中沒法用sleep(?)方法去等待它執行完畢。


1.2)使用join()方法解決:


        join()方法使當前執行緒阻塞,直至join()所屬的執行緒物件的run()方法執行完畢才繼續往下執行。

1.3)join()方法與異常

        join()方法內部使用的是wait()方法進行等待,如果當前執行緒物件被中斷,則當前執行緒物件出現異常。




        如果join()方法與interrupt()方法彼此相遇。本例中threadB出現異常。

1.4)join(long)的使用


         執行結果是等待了2s。將main()方法中的程式碼改為Thread.sleep(2000),發現執行結果是一樣的。那麼join(2000)與sleep(2000)究竟有何區別?

1.5)join(long)與sleep(long)的區別

        join(long)方法內部使用wait(long)方法實現,具有釋放鎖的特點,而Thread.sleep(long)方法不釋放鎖。





這裡由於執行緒threadB呼叫Thread.sleep(6000)方法,在6s內一直持有threadA物件鎖,所以執行緒threadC只有在6s後才能獲得threadA的鎖,從而呼叫threadA中的同步方法。

       如果將Thread.sleep(6000)改為threadA.join(6000),則執行結果如下:


        執行緒threadB呼叫threadA.join(6000),此方法會釋放threadA物件鎖,所以執行緒threadC可以呼叫threadA中的同步方法aService();

二、ThreadLocal類的使用

        可以使用public static 實現變數的共享,所有的執行緒都是用同一個public static 變數。如要實現每個執行緒都有自己的共享變數的值,則可以使用ThreadLocal類。

1)get()方法和set()方法


         可見第一次呼叫test.get()時返回的是null。下面驗證執行緒之間變數的隔離性:

2)執行緒之間變數的隔離性




          可見,兩個執行緒都向test物件set()資料,但每個執行緒都可以取出自己的資料。

3)重寫ThreadLocal類的initialValue()方法,使第一次呼叫get()方法時不再返回null。



         每個執行緒第一次呼叫ThreadLocal類的get()都會呼叫initialValue()方法,這裡重寫了initialValue()方法,兩個執行緒具有不同的初始值。