1. 程式人生 > >Java多執行緒之四種實現方式

Java多執行緒之四種實現方式

介紹

  1. 繼承Thread類,並重寫其run方法
  2. 實現Runnable介面
  3. 實現Callable介面通過FutureTask包裝器來建立Thread執行緒
  4. 執行緒池,使用ExecutorService、Callable、Future實現有返回結果的多執行緒。

其中前兩種方式執行緒執行完後都沒有返回值,後兩種是帶返回值的。

方式一

繼承Thread類建立執行緒,重寫run方法,開啟執行緒直接呼叫start方法,Thread類也是實現了Runnable介面

方式二

實現Runnable介面,然後作為引數去例項化一個Thread物件,呼叫start方法開啟執行緒。Thread的start方法執行自己的run方法,而它的run方法是呼叫建構函式引數物件的run方法(如果引數物件存在)。

    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

方式三

實現Callable介面通過FutureTask包裝器來建立Thread執行緒,Callable介面和Runnable介面的差別,前者有返回值,而且會丟擲檢查型異常,後者無返回值,也不會丟擲異常。

import java.util.concurrent.*;

public class ExecutorTest {
    public static void main
(String[] args){ Callable callable = new CallableDemo(); FutureTask futureTask = new FutureTask(callable); new Thread(futureTask).start(); } } class CallableDemo implements Callable{ @Override public Object call() throws Exception { Thread.sleep(10000); return
"OK"; } }

方式四

可返回值的任務必須實現Callable介面。類似的,無返回值的任務必須實現Runnable介面。FutureTask有一個建構函式,public FutureTask(Runnable runnable, V result),它可以把runnable介面和一個result物件包裝成一個callable介面,內部採用介面卡模式進行轉換,從而runnable介面也能返回值。 執行Callable任務後,可以獲取一個Future的物件,在該物件上呼叫get就可以獲取到Callable任務返回的Object了。 注意:get方法是阻塞的,即:執行緒無返回結果,get方法會一直等待。 再結合線程池介面ExecutorService就可以實現傳說中有返回結果的多執行緒了。

import java.util.concurrent.*;

public class ExecutorTest {
    public static void main(String[] args){
        Callable callable = new CallableDemo();
        FutureTask futureTask = new FutureTask(callable);
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        Future future = executorService.submit(futureTask);
        executorService.shutdown();
        try {
            future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
class CallableDemo implements Callable{

    @Override
    public Object call() throws Exception {
        Thread.sleep(10000);
        return "OK";
    }
}