java中有Future和FutureTask這兩個類
Future是一個接口,代表可以取消的任務,並可以獲得任務的執行結果
FutureTask 是基本的實現了Future和runnable接口
實現runnable接口,說明可以把FutureTask實例傳入到Thread中,在一個新的線程中執行。
實現Future接口,說明可以從FutureTask中通過get取到任務的返回結果,也可以取消任務執行(通過interreput中斷)
FutureTask可用於異步獲取執行結果或取消執行任務的場景。通過傳入Runnable或者Callable的任務給FutureTask,直接調用其run方法或者放入線程池執行,之后可以在外部通過FutureTask的get方法異步獲取執行結果,因此,FutureTask非常適合用於耗時的計算,主線程可以在完成自己的任務后,再去獲取結果。另外,FutureTask還可以確保即使調用了多次run方法,它都只會執行一次Runnable或者Callable任務,或者通過cancel取消FutureTask的執行等
1.FutureTask執行多任務計算的使用場景
利用FutureTask和ExecutorService,可以用多線程的方式提交計算任務,主線程繼續執行其他任務,當主線程需要子線程的計算結果時,在異步獲取子線程的執行結果。
package cn.zhm.day3;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class FutureTaskForMultiCompute {
public static void main(String[] args) throws InterruptedException,
ExecutionException {
FutureTaskForMultiCompute inst = new FutureTaskForMultiCompute();
// 創建任務集合
List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>();
ExecutorService execut = Executors.newScheduledThreadPool(5);
for (int i = 0; i < 10; i++) {
// 傳入Callable對象創建FutureTask對象
// inst.new ComputeTask(i, " "+i); 不太明白什么意思
FutureTask<Integer> task = new FutureTask<Integer>(
inst.new ComputeTask(i, "" + i));
// 把多個future放在集合中
taskList.add(task);
// 提交給線程池執行任務,也可以通過exec.invokeAll(taskList)一次性提交所有任務;
execut.submit(task);
System.out.println("所有計算任務提交完畢, 主線程接着干其他事情!");
}
Integer result = 0;
// 從future中取出值來
for (FutureTask<Integer> future : taskList) {
result = result + future.get();
}
// 打印求出來的值
System.out.println("result=" + result);
}
public class ComputeTask implements Callable<Integer> {
private Integer result = 0;
private String taskName = "";
ComputeTask(Integer result, String taskName) {
this.result = result;
this.taskName = taskName;
System.out.println("生成子線程計算任務: " + taskName);
}
public String getTaskName() {
return this.taskName;
}
@Override
public Integer call() throws Exception {
for (int i = 0; i < 10; i++) {
result += i;
}
Thread.sleep(5000);
System.out.println("子線程計算任務: " + taskName + " 執行完成!");
return result;
}
}
}

