Java多線程之FutureTask的介紹及使用
一、FutureTask的理解
FutureTask屬于java.util.concurrent 包;FutureTask表示可取消的異步計算。FutureTask類提供了一個Future的基本實現(xiàn) ,具有啟動和取消計算的方法,查詢計算是否完整,并檢索計算結果。結果只能在計算完成后才能檢索; 如果計算尚未完成,則get方法將阻止。 一旦計算完成,則無法重新啟動或取消計算(除非使用runAndReset()調(diào)用計算 )。
二、FutureTask類圖

從上面的FutureTask類圖中可以看出,F(xiàn)utureTask實現(xiàn)了RunnableFuture接口,RunnableFuture接口繼承了Runnable接口和Future接口,所以FutureTask兼?zhèn)銻unnable和Future兩種特性


三、FutureTask類中常用方法

1、構造方法
- public FutureTask(Callable callable) 創(chuàng)建一個 FutureTask ,它將在運行時執(zhí)行給定的 Callable 。 參數(shù): callable表示可調(diào)用任務 。
- public FutureTask(Runnable runnable,V result) 創(chuàng)建一個 FutureTask ,將在運行時執(zhí)行給定的 Runnable ,并安排 get將在成功完成后返回給定的結果。 參數(shù):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)嘗試取消執(zhí)行此任務。
- protected void set(V v)將此未來的結果設置為給定值,除非此未來已被設置或已被取消。
四、FutureTask類的使用示例
示例參考此博文:Java FutureTask類使用
案例場景
通過示例進行多任務計算,通過get()方法可以異步獲取執(zhí)行結果。
1、創(chuàng)建一個計算任務類,實現(xiàn)Callable接口,重寫call方法
package com.xz.thread.FutureTask;
import java.util.concurrent.Callable;
/**
* @description: 創(chuàng)建一個計算任務類,實現(xiàn)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("創(chuàng)建【計算任務】開始,計算任務名稱:" + taskName);
}
//計算任務的方法
@Override
public Integer call() throws Exception {
Integer result = 0;
for (int i = 1; i <=50; i++) {
result = +i;
}
System.out.println("【計算任務】"+taskName +"執(zhí)行完成。");
return result;
}
}
2、創(chuàng)建一個測試類
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<>();
//創(chuàng)建固定長度的線程池
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("所有【計算任務】提交完畢,主線程開始執(zhí)行");
System.out.println("【主線程任務】開始============");
//主線程睡眠5秒,模擬主線程做某些任務
try {
Thread.sleep(5000);
System.out.println("【主線程任務】開始執(zhí)行某些任務============");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("【主線程任務】結束============");
//用于打印任務執(zhí)行結果
Integer result = 0;
for (FutureTask<Integer> task : futureTasks) {
try {
//FutureTask的get()方法會自動阻塞,知道得到任務執(zhí)行結果為止
result += task.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
//關閉線程池
pool.shutdown();
System.out.println("多線程多任務執(zhí)行結果:" + result);
}
}
3、輸出結果如下:
創(chuàng)建【計算任務】開始,計算任務名稱:1
創(chuàng)建【計算任務】開始,計算任務名稱:2
創(chuàng)建【計算任務】開始,計算任務名稱:3
創(chuàng)建【計算任務】開始,計算任務名稱:4
創(chuàng)建【計算任務】開始,計算任務名稱:5
創(chuàng)建【計算任務】開始,計算任務名稱:6
創(chuàng)建【計算任務】開始,計算任務名稱:7
創(chuàng)建【計算任務】開始,計算任務名稱:8
創(chuàng)建【計算任務】開始,計算任務名稱:9
創(chuàng)建【計算任務】開始,計算任務名稱:10
所有【計算任務】提交完畢,主線程開始執(zhí)行
【主線程任務】開始============
【計算任務】1執(zhí)行完成。
【計算任務】2執(zhí)行完成。
【計算任務】6執(zhí)行完成。
【計算任務】7執(zhí)行完成。
【計算任務】9執(zhí)行完成。
【計算任務】10執(zhí)行完成。
【計算任務】8執(zhí)行完成。
【計算任務】4執(zhí)行完成。
【計算任務】3執(zhí)行完成。
【計算任務】5執(zhí)行完成。
【主線程任務】開始執(zhí)行某些任務============
【主線程任務】結束============
多線程多任務執(zhí)行結果:500

4、結論
通過FutureTask類的get()方法可用于異步獲取執(zhí)行結果,無論FutureTask調(diào)用多少次run()或者call()方法,它都能確保只執(zhí)行一次Runable或Callable任務。
到此這篇關于Java多線程之FutureTask的介紹及使用的文章就介紹到這了,更多相關Java FutureTask內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
springboot對接第三方微信授權及獲取用戶的頭像和昵稱等等
這篇文章主要介紹了springboot對接第三方微信授權及獲取用戶的頭像和昵稱等等,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01
解決阿里代碼規(guī)范檢測中方法缺少javadoc注釋的問題
這篇文章主要介紹了解決阿里代碼規(guī)范檢測中方法缺少javadoc注釋的問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08

