日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

三分鐘帶你搞懂 Future 玩法

來源: 責編: 時間:2024-01-16 10:17:03 265觀看
導讀一、摘要在前幾篇線程系列文章中,我們介紹了線程池的相關技術,任務執行類只需要實現Runnable接口,然后交給線程池,就可以輕松的實現異步執行多個任務的目標,提升程序的執行效率,比如如下異步執行任務下載。// 創建一個線程
一、摘要

在前幾篇線程系列文章中,我們介紹了線程池的相關技術,任務執行類只需要實現Runnable接口,然后交給線程池,就可以輕松的實現異步執行多個任務的目標,提升程序的執行效率,比如如下異步執行任務下載。gdM28資訊網——每日最新資訊28at.com

// 創建一個線程池ExecutorService executor = Executors.newFixedThreadPool(2);// 提交任務executor.submit(new Runnable() {    @Override    public void run() {        // 執行下載某文件任務        System.out.println("執行下載某文件任務");    }});

而實際上Runnable接口并不能滿足所有的需求,比如有些場景下,我們想要獲取任務執行的返回結果,Runnable接口因為無返回值,只能想辦法通過額外的方式來寫入和讀取,操作起來十分不便。gdM28資訊網——每日最新資訊28at.com

因此,從 JDK 1.5 開始,Java 標準庫提供了一個Callable接口,與Runnable接口相比,它的方法上多了一個返回值;同時Callable是一個泛型接口,可以返回指定類型的結果,比如如下的實現類!gdM28資訊網——每日最新資訊28at.com

public class Task implements Callable<String> {    @Override    public String call() throws Exception {        // 執行下載某文件任務        System.out.println("執行下載某文件任務");        return "xxx";    }}

問題來了,如何獲取異步執行的結果呢?gdM28資訊網——每日最新資訊28at.com

在 JDK 1.5 中,Java 標準庫還提供了一個Future接口,它可以用來獲取異步執行的結果。gdM28資訊網——每日最新資訊28at.com

下面我們一起來了解一下這個Future接口!gdM28資訊網——每日最新資訊28at.com

二、Future

Future接口,表示一個可能還沒有完成異步任務的結果,它提供了檢查任務是否已完成、以及等待任務完成并獲取結果等方法。gdM28資訊網——每日最新資訊28at.com

如果看過ExecutorService.submit()方法,會發現它的返回參數都是Future類型,Future類型的實例可以用來獲取異步任務執行的結果。gdM28資訊網——每日最新資訊28at.com

下面我們先來看一個簡單的示例,以便于更好的理解!gdM28資訊網——每日最新資訊28at.com

public class Task implements Callable<String> {        @Override    public String call() throws Exception {        // 執行下載某文件任務,并返回文件名稱        System.out.println("thread name:" +  Thread.currentThread().getName() + " 開始執行下載任務");        return "xxx.png";    }}
public class FutureTest {    public static void main(String[] args) throws Exception {        // 創建一個線程池        ExecutorService executor = Executors.newFixedThreadPool(1);        // 初始化一個任務        Callable<String> task = new Task();        // 提交任務并獲得Future的實例        Future<String> future = executor.submit(task);        // 從Future獲取異步執行返回的結果(可能會阻塞等待結果)        String result =future.get();        System.out.println("任務執行結果:" +  result);        // 任務執行完畢之后,關閉線程池(可選)        executor.shutdown();    }}

輸出結果如下:gdM28資訊網——每日最新資訊28at.com

thread name:pool-1-thread-1 開始執行下載任務任務執行結果:xxx.png

從以上的示例可以清晰的看到,當需要獲取異步線程的執行結果返回值時,通常需要搭配使用Future和Callable接口來實現,大體可以用如下步驟來概括:gdM28資訊網——每日最新資訊28at.com

  • 首先提交一個實現Callable接口的任務到線程池中
  • 然后獲取一個Future類型的對象
  • 最后在主線程中調用Future對象的get()方法,如果異步任務執行完成,就可以直接獲得結果;如果異步任務執行沒有完成,get()方法會阻塞,直到任務執行完成后才能獲取結果

分析源碼你會發現,Callable接口主要用途是定義一個支持返回結果的方法;重點實現主要集中在Future接口上。gdM28資訊網——每日最新資訊28at.com

下面我們重點來看下Future接口方法!gdM28資訊網——每日最新資訊28at.com

2.1、Future 接口方法

方法
gdM28資訊網——每日最新資訊28at.com

描述
gdM28資訊網——每日最新資訊28at.com

get()gdM28資訊網——每日最新資訊28at.com

獲取結果(會阻塞等待)
gdM28資訊網——每日最新資訊28at.com

get(long timeout, TimeUnit unit)gdM28資訊網——每日最新資訊28at.com

在指定的時間內獲取結果,如果超時,會拋異常并退出等待狀態
gdM28資訊網——每日最新資訊28at.com

cancel(boolean mayInterruptIfRunning)gdM28資訊網——每日最新資訊28at.com

嘗試取消當前任務,當傳入參數為true時,表示嘗試中斷任務的執行,false表示不中斷,繼續執行直到完成,如果取消成功,返回true;反之falsegdM28資訊網——每日最新資訊28at.com

isCancelled()gdM28資訊網——每日最新資訊28at.com

判斷任務是否已取消
gdM28資訊網——每日最新資訊28at.com

isDone()gdM28資訊網——每日最新資訊28at.com

判斷任務是否已完成
gdM28資訊網——每日最新資訊28at.com

2.2、Future 接口實現類

Future本質其實是一個接口,并不是具體的實現類,真正負責工作的還是它的實現類來完成。gdM28資訊網——每日最新資訊28at.com

我們還是以上文的線程池ExecutorService.submit()方法為例,看看它用的是哪種實現類!gdM28資訊網——每日最新資訊28at.com

分析一下源碼,會發現線程池用的實現類是FutureTask,關鍵核心源碼如下:gdM28資訊網——每日最新資訊28at.com

protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {    return new FutureTask<T>(callable);}

FutureTask類是一個實現了Future接口所有功能的具體類,可直接使用它來實現獲取異步任務執行的結果值。gdM28資訊網——每日最新資訊28at.com

FutureTask的工作原理其實也并不復雜,它接受一個Callable或者Runnable對象作為參數,然后在線程池執行器中執行該任務,最后通過get()方法可以同步等待獲取任務的執行結果。gdM28資訊網——每日最新資訊28at.com

真正起到關鍵作用的是,在FutureTask內部,封裝了一個狀態變量,用于記錄任務的狀態(等待、運行、完成、取消等),以及任務執行結果或異常信息,通過該狀態變量,我們可以判斷任務是否已完成、以及獲取任務的執行結果等信息。gdM28資訊網——每日最新資訊28at.com

因為FutureTask也實現了Runnable接口,因此我們也可以將FutureTask作為任務,提交給線程池執行器。gdM28資訊網——每日最新資訊28at.com

具體示例如下:gdM28資訊網——每日最新資訊28at.com

public class FutureTest {    public static void main(String[] args) throws Exception {        // 1.創建一個線程池        ExecutorService executor = Executors.newFixedThreadPool(1);        // 2.初始化一個任務        Callable<String> callable = new Task();        // 3.創建FutureTask對象        FutureTask<String> futureTask = new FutureTask<>(callable);        // 4.提交任務給執行器執行        executor.execute(futureTask);        // 5.獲取任務的執行結果        String result = futureTask.get(3, TimeUnit.SECONDS);        System.out.println("任務執行結果:" +  result);        // 6.關閉線程池(可選)        executor.shutdown();    }}

輸出結果同上!gdM28資訊網——每日最新資訊28at.com

如果想嘗試取消任務的執行,也可以通過如下方式來實現!gdM28資訊網——每日最新資訊28at.com

boolean isSuccess = futureTask.cancel(true);System.out.println("任務是否取消成功:" +  isSuccess);

除此之外,如果仔細的分析Future接口的類關系,會發現它的實現類非常的多,FutureTask只是它的一個基礎實現類而已,部分類關系圖如下!gdM28資訊網——每日最新資訊28at.com

圖片圖片gdM28資訊網——每日最新資訊28at.com

其它常用實現類簡介:gdM28資訊網——每日最新資訊28at.com

  • CompletableFuture:支持傳入回調對象,當異步任務完成或者發生異常時,自動調用回調對象的回調方法
  • ForkJoinTask:支持把一個大任務拆成多個小任務,然后并行執行,在多核 CPU 上可以顯著提升程序的執行效率
  • ScheduledFuture:支持周期性定時的執行任務,其中ScheduledFutureTask是一個私有類,只能通過ScheduledThreadPoolExecutor初始化操作

關于CompletableFuture、ForkJoinTask和ScheduledFuture,我們會在后面的文章中,再次單獨介紹具體的用法。gdM28資訊網——每日最新資訊28at.com

三、小結

本文主要圍繞Future接口用法做了一次簡單的知識總結,其中FutureTask類是Future接口中一個非常重要的實現類,通過它可以獲取異步任務執行的返回值,通常用于異步計算帶有返回值的任務。gdM28資訊網——每日最新資訊28at.com

限于篇幅的原因,本文沒有對FutureTask做過深入的原理講解,主要圍繞具體用法進行介紹,有興趣的朋友可以閱讀這篇文章《Java的Future機制詳解》,以便更清晰的了解它的實現原理。gdM28資訊網——每日最新資訊28at.com

如果有描述不對的地方,歡迎留言指出,共同進步!gdM28資訊網——每日最新資訊28at.com

四、參考

1.https://www.liaoxuefeng.com/wiki/1252599548343744/1306581155184674gdM28資訊網——每日最新資訊28at.com

2.https://www.cnblogs.com/xrq730/p/4872722.htmlgdM28資訊網——每日最新資訊28at.com

3.https://juejin.cn/post/7231074060787908663gdM28資訊網——每日最新資訊28at.com

4.https://zhuanlan.zhihu.com/p/54459770gdM28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-62362-0.html三分鐘帶你搞懂 Future 玩法

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: IT降本50%還賊穩!百萬訂單規模系統的技術治理實踐

下一篇: Swift 可選類型、可選綁定和可選鏈

標簽:
  • 熱門焦點
  • 帥氣純真少年!日本最帥初中生選美冠軍出爐

    日本第一帥哥初一生選美大賽冠軍現已正式出爐,冠軍是來自千葉縣的宗田悠良。日本一直熱衷于各種選美大賽,從&ldquo;最美JK&rdquo;起到&ldquo;最美女星&r
  • 三言兩語說透柯里化和反柯里化

    JavaScript中的柯里化(Currying)和反柯里化(Uncurrying)是兩種很有用的技術,可以幫助我們寫出更加優雅、泛用的函數。本文將首先介紹柯里化和反柯里化的概念、實現原理和應用
  • 為什么你不應該使用Div作為可點擊元素

    按鈕是為任何網絡應用程序提供交互性的最常見方式。但我們經常傾向于使用其他HTML元素,如 div span 等作為 clickable 元素。但通過這樣做,我們錯過了許多內置瀏覽器的功能。
  • 雅柏威士忌多款單品價格大跌,泥煤頂流也不香了?

    來源 | 烈酒商業觀察編 | 肖海林今年以來,威士忌市場開始出現了降溫跡象,越來越多不斷暴漲的網紅威士忌也開始悄然回歸市場理性。近日,LVMH集團旗下蘇格蘭威士忌品牌雅柏(Ardbeg
  • 破圈是B站頭上的緊箍咒

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之每年的暑期檔都少不了瞄準追劇女孩們的古偶劇集,2021年有優酷的《山河令》,2022年有愛奇藝的《蒼蘭訣》,今年卻輪到小破站抓住了追
  • 中國家電海外掘金正當時|出海專題

    作者|吳南南編輯|胡展嘉運營|陳佳慧出品|零態LT(ID:LingTai_LT)2023年,出海市場戰況空前,中國創業者在海外紛紛摩拳擦掌,以期能夠把中國的商業模式、創業理念、戰略打法輸出海外,他們依
  • 騰訊VS網易,最卷游戲暑期檔,誰能笑到最后?

    作者:無銹缽來源:財經無忌7月16日晚,上海1862時尚藝術中心。伴隨著幻象的精準命中,碩大的熒幕之上,比分被定格在了14:12,被寄予厚望的EDG戰隊以絕對的優勢戰勝了BLG戰隊,拿下了總決
  • iQOO 11S或7月上市:搭載“雞血版”驍龍8Gen2 史上最強5G Soc

    去年底,iQOO推出了“電競旗艦”iQOO 11系列,作為一款性能強機,iQOO 11不僅全球首發2K 144Hz E6全感屏,搭載了第二代驍龍8平臺及144Hz電競屏,同時在快充
  • OPPO K11搭載長壽版100W超級閃充:26分鐘充滿100%

    據此前官方宣布,OPPO將于7月25日也就是今天下午14:30舉辦新品發布會,屆時全新的OPPO K11將正式與大家見面,將主打旗艦影像,和同檔位競品相比,其最大的賣
Top 主站蜘蛛池模板: 长葛市| 灵寿县| 类乌齐县| 宁阳县| 阳朔县| 慈利县| 定远县| 新和县| 德化县| 宽城| 墨竹工卡县| 盖州市| 富源县| 陵水| 浦县| 承德市| 濉溪县| 秦安县| 财经| 上饶县| 博白县| 色达县| 广安市| 吴堡县| 横山县| 吴桥县| 渭南市| 灵川县| 庆安县| 高唐县| 金溪县| 五河县| 邮箱| 南宁市| 商河县| 杭锦旗| 三门县| 科尔| 旌德县| 乳源| 滕州市|