併發編程系列之Future類的主要功能介紹
1、什麼是Future類?
Future類:future類的是一種異步任務監視器,可以讓提交者可以監視任務的執行,同時可以取消任務的執行,也可以獲取任務返回結果
2、Future類的作用
比如在做一定的任務運算的時候,需要等待比較長時間,這個任務是比較耗時的,需要比較繁重的運算,比如加密、壓縮等等。如果一直在等程序執行完成是不明智的,這時可以將這個比較耗時的任務交給子線程執行,然後通過Future類監控線程執行,獲取返回的結果。這樣一來就提高了工作效率,這是一種異步的思想。
3、Future方法和用法
通過idea看一下Future類的類學習,可以看到這個類只有5個方法,基於jdk1.8:
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutExceptio
}
-
cancel(boolean mayInterruptIfRunning)
:取消任務的執行
執行這個方法時候,會有三種情況,- 第一種情況,任務還沒開始執行,調用了這個方法,這種情況比較好理解,這個任務會被正常取消,然後返回true
- 第二種情況,也比較簡單,假如任務已經執行完成或者是已經執行過一次取消任務的方法,這種情況如果再調用這個方法,是會取消失敗的,返回false。因爲任務無論是已完成還是已經被取消過了,都不能再被取消了
- 第三種情況,是任務正在執行,這種情況就會根據我們傳入的
mayInterruptIfRunning
參數進行分情況調用,如果這個值爲true,執行任務的線程就會收到一箇中斷的信號,然後執行中斷任務的邏輯,然後返回。如果這種值爲false,任務就不會被取消,繼續執行,同時會返回false,表示不執行取消任務操作
-
isCancelled()
:獲取是否取消了任務
這個方法用於判斷任務是否被取消了,比較簡單 -
isDone()
:任務是否執行完成
這個方法如果返回true,則表示執行完成了,返回false,表示還沒執行完成。這裏有一種特殊情況需要特別注意,就是如果執行任務的過程發生了Exception,這種情況還是會被當成執行完成的,因爲拋出Exception的任務,在”Future“也是不會執行的,所以都當成執行完成返回true -
get()
和get(long timeout, TimeUnit unit)
:獲取任務執行的返回值
get
方法最主要的作用就是獲取任務返回的結果,get
方法可能會發生以下 5 種情況:- 第一種情況:任務執行完成了,這種情況好辦,直接返回任務執行結果
- 第二種情況:任務還沒執行完成,這種情況有可能是任務本身業務比較複雜,需要花比較長時間,也有可能是放在線程池裏,然後線程池堆積了不少任務,所以需要線程等待,這種情況調用get方法,都會把當前的線程阻塞,直到任務完成再把結果返回回來。
- 第三種情況:執行任務過程拋出了異常,這種情況調用get會返回
ExecutionException
,不管實際的異常類型是什麼
public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService service = new ThreadPoolExecutor(10, 10, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue(10)); Future<Integer> future = service.submit(new CallableTask()); System.out.println(future.get()); service.shutdown(); } static class CallableTask implements Callable<Integer> { @Override public Integer call() throws Exception{ throw new IllegalArgumentException("callable exception"); } }
執行拋出異常:`Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: callable exception `
* 第四種情況:**任務被取消了**,這種情況調用get方法會拋出`CancellationException`
* 第五種情況:**任務超時執行**,這種情況是針對`get(long timeout, TimeUnit unit)`這個方法來說的,我們設置了`timeout`超時時長,如果超過了設定的值,就會拋出`TimeoutException`
package com.example.concurrent.future;
import java.util.Random;
import java.util.concurrent.*;
/**
* <pre>
* Future例子
* </pre>
* <p>
* <pre>
* @author nicky.ma
* 修改記錄
* 修改後版本: 修改人: 修改日期: 2021/08/28 17:11 修改內容:
* </pre>
*/
public class FutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService service = new ThreadPoolExecutor(10, 10,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue(10));
Future<Integer> future = service.submit(new CallableTask());
System.out.println(future.get());
service.shutdown();
}
static class CallableTask implements Callable<Integer> {
@Override
public Integer call() throws Exception{
Thread.sleep(1000L);
return new Random().nextInt();
}
}
}