Callable、Future、FutureTask的用法

package cn.com;

import java.util.concurrent.*;

/**
 * Copyright (C), 2018-2019
 * Callable、Future、FutureTask的用法
 * @Description: TODO
 * @Author: zhou
 * @Create: 2019/10/10 17:50
 * @Version 1.0.0
 */

public class ExecutorServiceTest {
    /**
     * Callable、Future 出現的緣由:
     *    咱們所熟知的建立線程的兩種方式,直接繼承Thread,或者實現Runnable接口.
     *    對於這兩種方式,有個通用的缺陷: 在執行完成任務後沒法獲取執行結果。
     *    若是須要獲取執行結果,就必須經過共享變量或者使用線程通訊的方式來達到效果,這樣使用起來就比較麻煩。
     *
     *    java 1.5開始,提供了Callable和Future,經過它們能夠在任務執行完畢以後獲得任務執行結果。
     *
     *    Callable接口表明一段能夠調用並返回結果的代碼;Future接口表示異步任務,是尚未完成的任務給出的將來結果。
     *    因此說Callable用於產生結果,Future用於獲取結果。
     *
     *   Future介紹
     *      在Future接口中聲明瞭5個方法,下面依次解釋每一個方法的做用:
     *   cancel方法用來取消任務,若是取消任務成功則返回true,若是取消任務失敗則返回false。參數mayInterruptIfRunning表示是否容許取消正在
     *   執行卻沒有執行完畢的任務,若是設置true,則表示能夠取消正在執行過程當中的任務。若是任務已經完成,則不管mayInterruptIfRunning爲true
     *   仍是false,此方法確定返回false,即若是取消已經完成的任務會返回false;若是任務正在執行,若mayInterruptIfRunning設置爲true,則
     *   返回true,若mayInterruptIfRunning設置爲false,則返回false;若是任務尚未執行,則不管mayInterruptIfRunning爲true仍是false,確定返回true。
     *      isCancelled方法表示任務是否被取消成功,若是在任務正常完成前被取消成功,則返回 true。
     *      isDone方法表示任務是否已經完成,若任務完成,則返回true;
     *      get()方法用來獲取執行結果,這個方法會產生阻塞,會一直等到任務執行完畢才返回;
     *      get(long timeout, TimeUnit unit)用來獲取執行結果,若是在指定時間內,還沒獲取到結果,就直接返回null。
     *   也就是說Future提供了三種功能:
     *   1)判斷任務是否完成;2)可以中斷任務;3)可以獲取任務執行結果。
     *   由於Future只是一個接口,因此是沒法直接用來建立對象使用的,所以就有了下面的FutureTask。FutureTask是Future惟一實現接口。
     */
    private static String callReturnStr ;
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println(CallableTest());
        RunnableTest();

    }

    public static String CallableTest(){
        ExecutorService executorService = Executors.newFixedThreadPool(1);// 申請一個固定長度的線程池
        try {
            // 建立一個任務,返回一個string
            Callable<String> callable = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    Thread.sleep(200);
                    callReturnStr = Thread.currentThread().getName() + " --CallableTest";
                    return callReturnStr;
                }
            };

            /**
             * 第一種方式:直接使用 ExecutorService的submit返回一個 Future
             */
            //Future<String> future = executorService.submit(callable); // 執行任務
            //callReturnStr = future.get(150, TimeUnit.MILLISECONDS);  // 設置超時時間

            /**
             * 第二種方式:
             */
            FutureTask<String> futureTask = new FutureTask<String>(callable);
            executorService.execute(futureTask);
            callReturnStr = futureTask.get(150, TimeUnit.MILLISECONDS);
            if(futureTask.isDone()){
                System.out.println("執行完成。");
                executorService.shutdown();
            }
        } catch (InterruptedException e) {
            //中端異常處理
            e.printStackTrace();
            callReturnStr = "中端異常處理";
            executorService.shutdown(); // 結束線程
        } catch (ExecutionException e) {
            //線程執行異常處理
            e.printStackTrace();  // 結束線程
            callReturnStr = "線程執行異常處理";
            executorService.shutdown();
        } catch (TimeoutException e) {
            //超時異常處理
            e.printStackTrace();  // 結束線程
            System.out.println("超時異常處理返回結果:" + callReturnStr); // 超時的返回結果
            callReturnStr = "超時異常處理";
            executorService.shutdown();
        }

        return callReturnStr;
    }

    public static void RunnableTest(){
        ExecutorService executorService = Executors.newFixedThreadPool(1);// 申請一個固定長度的線程池
        try {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "--RunnableTest");
                }
            };

            /**
             * ExecutorService接口中聲明瞭若干個submit方法的重載版本
             * submit(Runnable task, T result);
             * 其中 result是自定義的返回結果
             */
            //Future future = executorService.submit(runnable); // 執行任務
            Future future = executorService.submit(runnable, "自定義結果!"); // 執行任務
            future.get(150, TimeUnit.MILLISECONDS);  // 設置超時時間
            if(future.isDone()){
                System.out.println("執行完成。");
                executorService.shutdown();
            }
        }  catch (InterruptedException e) {
            //中端異常處理
            e.printStackTrace();
            callReturnStr = "中端異常處理";
            executorService.shutdown(); // 結束線程
        } catch (ExecutionException e) {
            //線程執行異常處理
            e.printStackTrace();  // 結束線程
            callReturnStr = "線程執行異常處理";
            executorService.shutdown();
        } catch (TimeoutException e) {
            //超時異常處理
            e.printStackTrace();  // 結束線程
            System.out.println("超時異常處理返回結果:" + callReturnStr); // 超時的返回結果
            callReturnStr = "超時異常處理";
            executorService.shutdown();
        }

    }

}

 

參考:https://blog.csdn.net/vking_wang/article/details/9470499java

相關文章
相關標籤/搜索