天天看點

有傳回值、可取消的異步任務--Future

之前線程池執行的任務是沒有傳回值的,但這種有傳回值的Future任務,可以适應更多的場景。

取消:boolean cancel(boolean mayInterruptIfRunning);
if(!future.isCancelled()){
	future.cancel();
}	
傳回值:V get() throws InterruptedException, ExecutionException;
try {
      futureResult = (String) future.get();
} catch (Exception e) {
      // 異常處理  
} 
           

舉個栗子:

1、正常流程,同步執行:

public static void main(String[] args) throws InterruptedException, ExecutionException {
        long startTime= System.currentTimeMillis();
        System.out.println("主線程任務開始執行");

        System.out.println("future 任務執行開始");
        Thread.sleep(6000);
        System.out.println("future 任務執行結束");
        String result = "2019";

        // 主線程任務
        mainThreadWork();

        String futureResult = result;
        System.out.println("futureResult:"+futureResult);
        System.out.println("主線程任務執行結束");
        long endTime= System.currentTimeMillis();

        System.out.println("時間消耗:"+ (endTime-startTime));
    }

    private static void mainThreadWork() throws InterruptedException {
        System.out.println("主線程任務--繼續執行,狀态1");
        Thread.sleep(3000);
        System.out.println("主線程任務--繼續執行,狀态2");
    }
           

控制台

主線程任務開始執行
future 任務執行開始
future 任務執行結束
主線程任務--繼續執行,狀态1
主線程任務--繼續執行,狀态2
futureResult:2019
主線程任務執行結束
時間消耗:9001
           

2、Future:

public static void main(String[] args) throws InterruptedException, ExecutionException {
        long startTime= System.currentTimeMillis();
        System.out.println("主線程任務開始執行");

        ExecutorService executorService = Executors.newFixedThreadPool(1);
        Future future = executorService.submit(()->{
            System.out.println("future 任務執行開始");
            Thread.sleep(6000);
//            if (1 == 1){
//                throw new Exception("111");
//            }
            System.out.println("future 任務執行結束");
            return "2019";
        });

        mainThreadWork();

        // 内部異常已抛出,此處無須catch
        String futureResult = (String) future.get();

        System.out.println("futureResult:"+futureResult);
        executorService.shutdown();

        System.out.println("主線程任務執行結束");
        long endTime= System.currentTimeMillis();

        System.out.println("時間消耗:"+ (endTime-startTime));
    }

    private static void mainThreadWork() throws InterruptedException {
        System.out.println("主線程任務--繼續執行,狀态1");
        Thread.sleep(3000);
        System.out.println("主線程任務--繼續執行,狀态2");
    }
           

控制台列印

主線程任務開始執行
主線程任務--繼續執行,狀态1
future 任務執行開始
主線程任務--繼續執行,狀态2
future 任務執行結束
futureResult:2019
主線程任務執行結束
時間消耗:6221
           

3、CompletableFuture

public static void main(String[] args) throws InterruptedException, ExecutionException {
        long startTime= System.currentTimeMillis();
        System.out.println("主線程任務開始執行");

        Future future = CompletableFuture.supplyAsync(()->{
            System.out.println("future 任務執行開始");
            try {
                Thread.sleep(6000);
            } catch (InterruptedException e) {
            }
//            if (1 == 1){
//                throw new RuntimeException("111");
//            }
            System.out.println("future 任務執行結束");
            return "2019";
        });

        mainThreadWork();

        String futureResult = (String) future.get();
        System.out.println("futureResult:"+futureResult);

        System.out.println("主線程任務執行結束");
        long endTime= System.currentTimeMillis();

        System.out.println("時間消耗:"+ (endTime-startTime));
    }

    private static void mainThreadWork() throws InterruptedException {
        System.out.println("主線程任務--繼續執行,狀态1");
        Thread.sleep(3000);
        System.out.println("主線程任務--繼續執行,狀态2");
    }
           

控制台

主線程任務開始執行
主線程任務--繼續執行,狀态1
future 任務執行開始
主線程任務--繼續執行,狀态2
future 任務執行結束
futureResult:2019
主線程任務執行結束
時間消耗:6177