看完本文,再也不怕問java線程創建的幾種方式了
- 2019 年 10 月 4 日
- 筆記
- 繼承Thread類
- 實現Runnable接口
- 實現Callable接口(
JDK1.5
+)
如果想了解具體怎麼創建的,請往下看:
繼承Thread類
//繼承Thread public class ExtendThread extends Thread{ //線程執行體 @Override public void run() { //do something System.out.println("繼承Thread創建線程"); //無返回值 } } public class ThreadCreateDemo { public static void main(String[] args) { //創建一個線程 ExtendThread extendThread = new ExtendThread(); //調用start方法啟動線程 extendThread.start(); //沒有返回值 } }
輸出:
繼承Thread創建線程
注意
使用繼承Thread類的方法來創建線程類時候,多個線程之間是無法共享線程類的實例變量的。
實現Runnable接口
覆寫Runnable接口實現多線程可以避免單繼承局限, 當子類實現Runnable接口,此時子類和Thread的代理模式(子類負責真實業務的操作,thread負責資源調度與線程創建輔助真實業務)。
//實現Runnable接口 public class ImplRunnable implements Runnable { //線程實行體 @Override public void run() { //do something System.out.println("實現Runnable創建線程"); //沒有返回值 } } public class ThreadCreateDemo { public static void main(String[] args) { ImplRunnable implRunnable = new ImplRunnable(); Thread thread = new Thread(implRunnable); //啟動線程 thread.start(); } }
輸出:
實現Runnable創建線程
注意
Runnable對象僅僅作為Thread對象的target,Runnable實現類里包含的run方法僅僅作為線程的執行體,而實際的線程對象依舊是Thread實例,只是該Thread線程負責執行器target的方法。
覆寫Callable接口
//實現Callable返回值類型為Integer類型 public class ImplCallable implements Callable<Integer> { //該call()方法將作為線程執行體,並且有返回值 @Override public Integer call() throws Exception { //do something System.out.println("實現Callable接口創建線程,返回類型為Integer類型"); return 999; } } public class ThreadCreateDemo { public static void main(String[] args) throws ExecutionException, InterruptedException { Callable<Integer> callable = new ImplCallable(); FutureTask<Integer> futureTask = new FutureTask<>(callable); Thread thread = new Thread(futureTask); thread.start(); //獲取返回值futureTask.get() System.out.println(futureTask.get()); } }
輸出:
999
注意
Callable接口有泛型限制,Callable接口裡的泛型形參類型與call方法返回值類型相同,而且Callable接口是函數式接口,因此可以使用Lambda表達式創建Callable對象。
三種方式的對比
通過繼承Thread類或者實現Runnable接口、Callable接口都可以實現多線程,不過實現Runnable接口與實現Callable接口的方式基本相同,只是Callabl接口裡定義的方法返回值,可以聲明拋出異常而已。因此將實現Runnable接口和實現Callable接口歸為一種方式。這種方式與繼承Thread方式之間的主要差別如下。

採用實現Runnable、Callable接口的方式創建線程的優缺點:
優點
線程類只是實現了Runnable或者Callable接口,還可以繼承其他類。這種方式下,多個線程可以共享一個target對象,所以非常適合多個相同線程來處理同一份資源的情況,從而可以將CPU、代碼和數據分開,形成清晰的模型,較好的體現了面向對象的思想。
缺點
編程稍微複雜一些,如果需要訪問當前線程,則必須使用
Thread.currentThread()方法

采 用繼承Thread類的方式創建線程的優缺點:
缺點
因為線程類已經繼承了Thread類,Java語言是單繼承的,所以就不能再繼承其他父類了。
優點
編寫簡單,如果需要訪問當前線程,則無需使用
Thread.currentThread()方法,直接使用this即可獲取當前線程
鑒於上面分析,因此一般建議採用實現Runnable或Callable接口來創建多線程