1. 程式人生 > 實用技巧 >多執行緒常見的三種實現方式

多執行緒常見的三種實現方式

注意: 這隻說明最常見的三種實現方式,並不說明執行緒池.

三種實現方案

  • 繼承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類中的方法 可擴充套件性較差,不能繼承其他類