Java多線程之FutureTask的介紹及使用
一、FutureTask的理解
FutureTask屬於java.util.concurrent 包;FutureTask表示可取消的異步計算。FutureTask類提供瞭一個Future的基本實現 ,具有啟動和取消計算的方法,查詢計算是否完整,並檢索計算結果。結果隻能在計算完成後才能檢索; 如果計算尚未完成,則get方法將阻止。 一旦計算完成,則無法重新啟動或取消計算(除非使用runAndReset()調用計算 )。
二、FutureTask類圖
從上面的FutureTask類圖中可以看出,FutureTask實現瞭RunnableFuture接口,RunnableFuture接口繼承瞭Runnable接口和Future接口,所以FutureTask兼備Runnable和Future兩種特性
三、FutureTask類中常用方法
1、構造方法
- public FutureTask(Callable callable) 創建一個 FutureTask ,它將在運行時執行給定的 Callable 。 參數: callable表示可調用任務 。
- public FutureTask(Runnable runnable,V result) 創建一個 FutureTask ,將在運行時執行給定的 Runnable ,並安排 get將在成功完成後返回給定的結果。 參數:runnable 表示可運行的任務 ;result 表示成功完成後返回的結果。
2、常用的方法
- public boolean isCancelled() 如果此任務在正常完成之前取消,則返回 true 。
- public boolean isDone() 返回true如果任務已完成。
- public V get() 等待計算完成,然後檢索其結果。
- public V get(long timeout, TimeUnit unit)如果需要等待最多在給定的時間計算完成,然後檢索其結果(如果可用)。
- public boolean cancel(boolean mayInterruptIfRunning)嘗試取消執行此任務。
- protected void set(V v)將此未來的結果設置為給定值,除非此未來已被設置或已被取消。
四、FutureTask類的使用示例
示例參考此博文:Java FutureTask類使用
案例場景
通過示例進行多任務計算,通過get()方法可以異步獲取執行結果。
1、創建一個計算任務類,實現Callable接口,重寫call方法
package com.xz.thread.FutureTask; import java.util.concurrent.Callable; /** * @description: 創建一個計算任務類,實現Callable接口,重寫call方法 * @author: xz * @create: 2021-06-02 22:06 */ public class ComputeTask implements Callable<Integer> { private String taskName;//任務名稱 //任務構造器 public ComputeTask(String taskName) { this.taskName = taskName; System.out.println("創建【計算任務】開始,計算任務名稱:" + taskName); } //計算任務的方法 @Override public Integer call() throws Exception { Integer result = 0; for (int i = 1; i <=50; i++) { result = +i; } System.out.println("【計算任務】"+taskName +"執行完成。"); return result; } }
2、創建一個測試類
package com.xz.thread.FutureTask; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; /** * @description: * @author: xz * @create: 2021-06-01 22:44 */ public class Demo { public static void main(String[] args) { //任務集合 List<FutureTask<Integer>> futureTasks = new ArrayList<>(); //創建固定長度的線程池 ExecutorService pool = Executors.newFixedThreadPool(5); for (int i = 1; i <= 10; i++) { //實例化FutureTask,傳入計算任務類 FutureTask<Integer> futureTask = new FutureTask<>(new ComputeTask(i + "")); //添加到任務集合中 futureTasks.add(futureTask); //提交任務到線程池 pool.submit(futureTask); } System.out.println("所有【計算任務】提交完畢,主線程開始執行"); System.out.println("【主線程任務】開始============"); //主線程睡眠5秒,模擬主線程做某些任務 try { Thread.sleep(5000); System.out.println("【主線程任務】開始執行某些任務============"); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("【主線程任務】結束============"); //用於打印任務執行結果 Integer result = 0; for (FutureTask<Integer> task : futureTasks) { try { //FutureTask的get()方法會自動阻塞,知道得到任務執行結果為止 result += task.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } //關閉線程池 pool.shutdown(); System.out.println("多線程多任務執行結果:" + result); } }
3、輸出結果如下:
創建【計算任務】開始,計算任務名稱:1
創建【計算任務】開始,計算任務名稱:2
創建【計算任務】開始,計算任務名稱:3
創建【計算任務】開始,計算任務名稱:4
創建【計算任務】開始,計算任務名稱:5
創建【計算任務】開始,計算任務名稱:6
創建【計算任務】開始,計算任務名稱:7
創建【計算任務】開始,計算任務名稱:8
創建【計算任務】開始,計算任務名稱:9
創建【計算任務】開始,計算任務名稱:10
所有【計算任務】提交完畢,主線程開始執行
【主線程任務】開始============
【計算任務】1執行完成。
【計算任務】2執行完成。
【計算任務】6執行完成。
【計算任務】7執行完成。
【計算任務】9執行完成。
【計算任務】10執行完成。
【計算任務】8執行完成。
【計算任務】4執行完成。
【計算任務】3執行完成。
【計算任務】5執行完成。
【主線程任務】開始執行某些任務============
【主線程任務】結束============
多線程多任務執行結果:500
4、結論
通過FutureTask類的get()方法可用於異步獲取執行結果,無論FutureTask調用多少次run()或者call()方法,它都能確保隻執行一次Runable或Callable任務。
到此這篇關於Java多線程之FutureTask的介紹及使用的文章就介紹到這瞭,更多相關Java FutureTask內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Java並發教程之Callable和Future接口詳解
- Java多線程 Callable、Future 和FutureTask
- Java使用Runnable和Callable實現多線程的區別詳解
- Java中Future和FutureTask的示例詳解及使用
- Java多線程教程之如何利用Future實現攜帶結果的任務