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; } } }