併發編程系列之Future類的主要功能介紹

併發編程系列之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();
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章