Java多執行緒之四種實現方式
阿新 • • 發佈:2018-12-13
介紹
- 繼承Thread類,並重寫其run方法
- 實現Runnable介面
- 實現Callable介面通過FutureTask包裝器來建立Thread執行緒
- 執行緒池,使用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";
}
}