多執行緒常見的三種實現方式
阿新 • • 發佈:2020-10-12
注意: 這隻說明最常見的三種實現方式,並不說明執行緒池.
三種實現方案
- 繼承Thread類的方式進行實現
- 實現Runnable介面的方式進行實現
- 利用Callable和Future介面方式實現
方案一:繼承Thread類
- 定義一個MyThread繼承Thread
- 在MyThread類中重寫run方法
- 建立MyThread類的物件
- 起動執行緒
public class Threadtest { public static void main(String[] args) { MyThread t1 = new MyThread(); t1.start(); } } class MyThread extends Thread{ @Override public void run() { //這裡的程式碼就是執行緒開啟之後要執行的程式碼 for (int i = 0; i < 100; i++) { System.out.println("執行緒開啟了:"+i); } } }
為什麼要重寫run()方法?
因為run方法是用來封裝被執行緒執行的程式碼
run()方法和start()方法的區別
run():封裝執行緒執行的程式碼,直接呼叫,相當於普通方法的呼叫,並沒有開啟執行緒
start():啟動執行緒;然後由JVM呼叫此執行緒的run方法
方案二:實現Runnable介面
- 定義一個MyRunnable類實現Runnable介面 //這裡可以選擇lambda表示式
- 在MyRunnable類中重寫run()方法
- 建立MyRunnable類的物件
- 建立Thread類的物件,把MyRunnable物件作為構造方法的引數
- 啟動執行緒
public class MyRunnableTest { public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); } } class MyRunnable implements Runnable{ @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("Runnable啟動執行緒的方式:"+i); } } }
方案三:Callable和Future
- 定義一個類MyCallable實現Callable介面
- 在MyCallable類中重寫call()方法
- 建立MyCallable類的物件
- 建立Future的實現類FutureTask物件,把MyCallable物件作為構造方法的引數
- 建立Thread類的物件,把FutureTask物件作為構造方法的引數
- 啟動執行緒
*在呼叫get()方法,就可以獲取執行緒結束後的結果
public class MyCallableTest { public static void main(String[] args) throws ExecutionException, InterruptedException { MyCallable myCallable = new MyCallable(); FutureTask<String> futureTask = new FutureTask<>(myCallable); Thread thread = new Thread(futureTask); thread.start(); //執行緒開啟之後,可以通過get方法獲得執行緒返回的資料 //一定是要執行緒開啟之後 String res = futureTask.get(); System.out.println("返回的結果為:"+res); } } //這裡的Callable是泛型,裡面指定String是設定的返回值型別為String class MyCallable implements Callable<String>{ @Override public String call() throws Exception { for (int i = 0; i < 100; i++) { System.out.println("跟女孩表白次數:"+i); } return "OK"; } }
三種方式簡單對比
- | 優點 | 缺點 |
---|---|---|
實現Runnable,Callable介面 | 擴充套件性強,實現該介面的同時還可以繼承其他的類 | 程式設計相對複雜,不能直接使用Thread類中的方法 |
繼承Thread類 | 程式設計比較簡單,可以直接使用Thread類中的方法 | 可擴充套件性較差,不能繼承其他類 |