不久前我寫了一篇關於Java Callable Future介面的文章,我們可以使用這些介面來獲得執行緒的並行處理優勢,同時它們能夠將值返回給調用程序。FutureTask是Future介面的具體實現基礎,並提供異步處理。它包含了啟動和取消任務的方法,以及可以返回FutureTask狀態的方法,無論它是完成還是取消。我們需要一個可調用的對象來創建一個future任務,然後我們可以使用Java Thread Pool Executor來異步處理這些任務。讓我們通過一個簡單的範例來看看FutureTask的用法。由於FutureTask需要一個可調用的對象,我們將創建一個簡單的Callable實現。
package com.journaldev.threads;
import java.util.concurrent.Callable;
public class MyCallable implements Callable {
private long waitTime;
public MyCallable(int timeInMillis){
this.waitTime=timeInMillis;
}
@Override
public String call() throws Exception {
Thread.sleep(waitTime);
//返回執行此可調用任務的執行緒名稱
return Thread.currentThread().getName();
}
}
以下是FutureTask方法的示例,展示了FutureTask的常用方法。
package com.journaldev.threads;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class FutureTaskExample {
public static void main(String[] args) {
MyCallable callable1 = new MyCallable(1000);
MyCallable callable2 = new MyCallable(2000);
FutureTask futureTask1 = new FutureTask(callable1);
FutureTask futureTask2 = new FutureTask(callable2);
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(futureTask1);
executor.execute(futureTask2);
while (true) {
try {
if(futureTask1.isDone() && futureTask2.isDone()){
System.out.println("Done");
//關閉執行器服務
executor.shutdown();
return;
}
if(!futureTask1.isDone()){
//無限期等待未來任務完成
System.out.println("FutureTask1 output="+futureTask1.get());
}
System.out.println("Waiting for FutureTask2 to complete");
String s = futureTask2.get(200L, TimeUnit.MILLISECONDS);
if(s !=null){
System.out.println("FutureTask2 output="+s);
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}catch(TimeoutException e){
//什麼也不做
}
}
}
}
當我們運行上述程序時,您會注意到在某段時間內它不會輸出任何東西,這是因為`FutureTask`的`get()`方法會等待任務完成,然後返回輸出對象。還有一個重載的方法,可以僅等待指定的時間,我們在`futureTask2`中使用了它。同時注意使用`isDone()`方法確保程序在所有任務執行完畢後終止。上述程序的輸出將是:
FutureTask1 output=pool-1-thread-1
Waiting for FutureTask2 to complete
Waiting for FutureTask2 to complete
Waiting for FutureTask2 to complete
Waiting for FutureTask2 to complete
Waiting for FutureTask2 to complete
FutureTask2 output=pool-1-thread-2
Done
儘管`FutureTask`看起來沒有太多好處,但當我們想要覆蓋一些`Future`接口的方法並且不想實現`Future`接口的每個方法時,它就變得很方便。
Source:
https://www.digitalocean.com/community/tutorials/java-futuretask-example-program