【多線程學習筆記2】線程的創建與啓動

1 線程的創建與啓動

Java使用Thread類代表線程,所有的線程對象都必須是Thread類或其子類的實例。

1.1 繼承Thread類創建線程類

通過繼承Thread類來創建並啓動多線程的步驟如下:
(1)定義Thread類的子類,並重寫該類的run()方法,該run()方法的方法體就代表了線程需要完成的任務,因此把run()方法稱爲線程執行體。
(2)創建Thread子類的實例,即創建了線程對象。
(3)調用線程對象的start()方法來啓動該線程。

注意:
(1)進行多線程編程時,不要忘記了Java程序運行時默認的主線程,main()方法的方法體就是主線程的線程執行體。
(2)使用繼承Thread類的方法來創建線程類時,因爲程序每次創建線程對象時都需要創建一個Thread子類的實例對象,所以多個線程之間無法共享線程類的實例變量。

1.2 實現Runnable接口創建線程類

使用Runnable接口來創建並啓動多線程的步驟如下:
(1)定義Runnable接口的實現類,並重寫該接口的run()方法,該run()方法的方法體就是該線程的線程執行體。
(2)創建Runnable實現類的實例,並以此實例作爲Thread的target來創建Thread對象,該Thread對象纔是真正的線程對象。
(3)調用線程對象的start()方法來啓動該線程。

注意:
(1)Runnable對象僅僅作爲Thread對象的target,Runnable實現類裏包含的run()方法僅作爲線程執行體。而實際的線程對象依然是Thread實例,只是該Thread線程負責執行其target的run()方法。
(2)採用Runnable接口的方式創建的多個線程可以共享線程類的實例變量,這是因爲在這種方式下,程序所創建的Runnable對象只是線程的target,而多個線程可以共享同一個target,所以多個線程可以共享同一個線程類(實際上是線程的target類)的實例變量。

1.3 使用Callable和Future創建線程

通過實現Runnable接口創建多線程時,Thread類的作用就是把run()方法包裝成線程執行體。

也許受此啓發,從Java 5開始,Java提供了Callable接口,這個接口像是Runnable接口的增強,因爲Callable接口提供了一個call()方法作爲線程執行體,同時call()方法可以有返回值,而且可以聲明並拋出異常。

同時Java 5提供了Future接口來代表Callable接口裏call()方法的返回值,併爲Future接口提供了一個FutureTask實現類,該實現類實現了Future接口,並實現了Runnable接口,也就是說它可以作爲Thread類的target。

創建並啓動有返回值的線程的步驟如下:
(1)創建Callable接口的實現類,並實現call()方法,該call()方法將作爲線程執行體,且該call()方法有返回值,再創建Callable實現類的實例。
(2)使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的call()方法的返回值。
(3)使用FutureTask對象作爲Thread對象的target創建並啓動新線程。
(4)調用FutureTask對象的get()方法來獲得子線程執行結束後的返回值。

1.4 創建線程的三種方式對比

通過繼承Thread類或實現Runnable、Callable接口都可以實現多線程,不過實現Runnable接口與實現Callable接口的方式基本相同,只是Callable接口裏定義的方法有返回值,可以聲明拋出異常而已,所以這兩個可以歸爲一類。那這種方式與繼承Thread方式之間的主要差別如下。

採用實現Runnable、Callable接口的方式創建多線程的優缺點:
(1)線程類只是實現了Runnable接口或Callable接口,還可以繼承其他類。
(2)這種方式下,多個線程可以共享同一個target對象,非常適合多個相同線程處理同一份資源的情況。
(3)劣勢是編程稍顯複雜,訪問當前線程,必須使用Thread.currentThread()方法。

採用繼承Thread類的方式創建多線程的優缺點:
(1)編寫簡單,若需要訪問當前線程,無須使用Thread.currentThread()方法,直接使用this即可獲得當前線程。
(2)劣勢是,線程類已經繼承了Thread類,就不能再繼承其他父類了。

也是因爲上面優劣勢,一般是推薦採用實現Runnable接口、Callable接口的方式來創建多線程。對於不需要返回值的就用實現Runnable接口方式,對於需要返回值的就用實現Callable方式來創建。


寫在最後的話:

搞開發這麼多年了,多線程也用了蠻多了,對於多線程創建和啓動的內容也學過很多遍了,但一直侷限於應付面試,始終是有點蒙圈的。另外畢竟現在用多線程,都是依賴線程池,我是感覺很少自己直接去new一個線程對象了,所以之前即使有用到,也更多時候都是用的懵懵的。

這次再次學習並整理一下筆記,其實也是受了面試的啓發。話說再一次學習,並回顧自己的開發經驗,還是很大收穫的。總結一下,也方便自己日後再複習回顧吧。

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