最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java線程池FutureTask實(shí)現(xiàn)原理詳解

 更新時(shí)間:2018年02月06日 08:40:46   作者:那個(gè)天真的人  
這篇文章主要介紹了Java線程池FutureTask實(shí)現(xiàn)原理詳解,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下

前言

線程池可以并發(fā)執(zhí)行多個(gè)任務(wù),有些時(shí)候,我們可能想要跟蹤任務(wù)的執(zhí)行結(jié)果,甚至在一定時(shí)間內(nèi),如果任務(wù)沒有執(zhí)行完成,我們可能還想要取消任務(wù)的執(zhí)行,為了支持這一特性,ThreadPoolExecutor提供了 FutureTask 用于追蹤任務(wù)的執(zhí)行和取消。本篇介紹FutureTask的實(shí)現(xiàn)原理。

類視圖

為了更好的理解FutureTask的實(shí)現(xiàn)原理,這里先提供幾個(gè)重要接口和類的結(jié)構(gòu),如下圖所示:

RunnableAdapter

ThreadPoolExecutor提供了submit接口用于提交任務(wù),submit支持Runnable和Callable兩種不同的接口,為了提供統(tǒng)一的對(duì)外接口,jdk在內(nèi)部把Runnable給包裝成了一個(gè)Callable,這一切是通過RunnableAdapter這個(gè)適配器來實(shí)現(xiàn)的。如下為RunnableAdapter的源碼:

static final class RunnableAdapter<T> implements Callable<T> {
    final Runnable task;
    final T result;
    RunnableAdapter(Runnable task, T result) {
      this.task = task;
      this.result = result;
    }
    public T call() {
      task.run();
      return result;
    }
  }

RunnableAdapter是Callable 的實(shí)現(xiàn)類,實(shí)現(xiàn)了call方法,而call方法僅僅是調(diào)用task.run(),然后return result,這樣就能夠確保在內(nèi)部只需要統(tǒng)一處理Callable接口。

FutureTask實(shí)現(xiàn)原理

通過上一小節(jié)的了解,我們知道提交的Runnable任務(wù)在內(nèi)部統(tǒng)一被轉(zhuǎn)換為Callable任務(wù)。查看submit方法的返回值,為一個(gè)Future,實(shí)際上這個(gè)Futrue為FutureTask實(shí)例,通過此實(shí)例,調(diào)用get方法,可以阻塞當(dāng)前線程,直到任務(wù)運(yùn)行完畢,返回結(jié)果。

整個(gè)調(diào)用鏈條如下所示:

worker thread -> futureTask.run() -> callable.call() -> task.run()

如果提交的是Callable任務(wù),則只有前面三個(gè)調(diào)用。

為了更好的展示整個(gè)流程,下面舉例演示一遍執(zhí)行流程。

1、 向線程池submit一個(gè)Callable任務(wù)(Runnable也會(huì)被轉(zhuǎn)為Callable), 這時(shí)候Callable被傳入一個(gè)FutureTask實(shí)例中,如下所示:

2、線程池使用一個(gè)線程,執(zhí)行這個(gè) FutureTask 任務(wù),

線程執(zhí)行任務(wù)過程比較簡(jiǎn)單,最終會(huì)調(diào)用Callable.call()或者是 Runnable.run()方法,然后得到一個(gè)結(jié)果,把結(jié)果存儲(chǔ)在FutureTask實(shí)例的outcome屬性中,同時(shí)把狀態(tài)修改為NORMAL,表明任務(wù)已經(jīng)執(zhí)行完畢,可以獲取結(jié)果了。

我們假設(shè)在執(zhí)行 callable.call() 過程中有多個(gè)線程調(diào)用了 同個(gè)FutureTask實(shí)例的get方法,這時(shí)候,這些線程會(huì)被阻塞,存于一個(gè)棧中, 如下圖所示:

線程1,2,3調(diào)用FutureTask.get方法,由于任務(wù)未執(zhí)行結(jié)束,這時(shí)候,三個(gè)線程都將被阻塞休眠,F(xiàn)utureTask中有一個(gè)棧,用于存放等待線程,棧頂指針為 FutureTask.waiters引用,當(dāng)任務(wù)執(zhí)行完畢后,會(huì)迭代喚醒整個(gè)棧中的線程,這時(shí)候,各個(gè)線程都將被喚醒,并且可以順利拿到任務(wù)的執(zhí)行結(jié)果(執(zhí)行結(jié)果存于 FutureTask.outcome) 。

FutureTask還支持任務(wù)的取消功能,這一切都是通過 FutureTask的state狀態(tài)來協(xié)調(diào)多個(gè)線程的。

總結(jié)

FutureTask接口是一種實(shí)現(xiàn)機(jī)制,提供我們對(duì)任務(wù)的執(zhí)行的跟蹤以及控制,相比于線程池本身,比較簡(jiǎn)單,相信不難理解。

以上就是本文關(guān)于Java線程池FutureTask實(shí)現(xiàn)原理詳解的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!

相關(guān)文章

  • Java線程池ForkJoinPool(工作竊取算法)的使用

    Java線程池ForkJoinPool(工作竊取算法)的使用

    Fork就是把一個(gè)大任務(wù)切分為若干個(gè)子任務(wù)并行地執(zhí)行,Join就是合并這些子任務(wù)的執(zhí)行結(jié)果,最后得到這個(gè)大任務(wù)的結(jié)果。Fork/Join?框架使用的是工作竊取算法。本文主要介紹了ForkJoinPool的使用,需要的可以參考一下
    2022-11-11
  • Spring注解之@Import使用方法講解

    Spring注解之@Import使用方法講解

    @Import是Spring基于Java注解配置的主要組成部分,下面這篇文章主要給大家介紹了關(guān)于Spring注解之@Import的簡(jiǎn)單介紹,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • Spring WebFlux實(shí)現(xiàn)參數(shù)校驗(yàn)的示例代碼

    Spring WebFlux實(shí)現(xiàn)參數(shù)校驗(yàn)的示例代碼

    請(qǐng)求參數(shù)校驗(yàn),在實(shí)際的應(yīng)用中很常見,網(wǎng)上的文章大部分提供的使用注解的方式做參數(shù)校驗(yàn)。本文主要介紹 Spring Webflux Function Endpoint 使用 Spring Validation 來校驗(yàn)請(qǐng)求的參數(shù)。感興趣的可以了解一下
    2021-08-08
  • Java是自學(xué)好還是參加培訓(xùn)班好?

    Java是自學(xué)好還是參加培訓(xùn)班好?

    這篇文章主要介紹了Java是自學(xué)好還是參加培訓(xùn)班好這一問題,給大家介紹了哪些人適合自學(xué)java,哪些人適合java培訓(xùn)班學(xué)習(xí),大家可以看看內(nèi)容詳情
    2018-04-04
  • Maven方式構(gòu)建SpringBoot項(xiàng)目的實(shí)現(xiàn)步驟(圖文)

    Maven方式構(gòu)建SpringBoot項(xiàng)目的實(shí)現(xiàn)步驟(圖文)

    Maven是一個(gè)強(qiáng)大的項(xiàng)目管理工具,可以幫助您輕松地構(gòu)建和管理Spring Boot應(yīng)用程序,本文主要介紹了Maven方式構(gòu)建SpringBoot項(xiàng)目的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • java 交換兩個(gè)數(shù)據(jù)的方法實(shí)例詳解

    java 交換兩個(gè)數(shù)據(jù)的方法實(shí)例詳解

    這篇文章主要介紹了java 交換兩個(gè)數(shù)據(jù)的方法實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • 使用Java實(shí)現(xiàn)文件夾的遍歷操作指南

    使用Java實(shí)現(xiàn)文件夾的遍歷操作指南

    網(wǎng)上大多采用java遞歸的方式遍歷文件夾下的文件,這里我不太喜歡遞歸的風(fēng)格,這篇文章主要給大家介紹了關(guān)于使用Java實(shí)現(xiàn)文件夾的遍歷操作的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Java使用JDBC驅(qū)動(dòng)連接MySQL數(shù)據(jù)庫(kù)

    Java使用JDBC驅(qū)動(dòng)連接MySQL數(shù)據(jù)庫(kù)

    這篇文章主要為大家詳細(xì)介紹了Java使用JDBC驅(qū)動(dòng)連接MySQL數(shù)據(jù)庫(kù)的具體步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 使用Spring和Redis創(chuàng)建處理敏感數(shù)據(jù)的服務(wù)的示例代碼

    使用Spring和Redis創(chuàng)建處理敏感數(shù)據(jù)的服務(wù)的示例代碼

    許多公司處理的用戶敏感數(shù)據(jù)由于法律限制不能永久存儲(chǔ),根據(jù)規(guī)定,這些數(shù)據(jù)的存儲(chǔ)時(shí)間不能超過預(yù)設(shè)期限,并且最好在用于服務(wù)目的之后就將其刪除,解決這個(gè)問題有多種可能的方案,在本文中,我想展示一個(gè)利用 Spring 和 Redis 處理敏感數(shù)據(jù)的應(yīng)用程序的簡(jiǎn)化示例
    2025-04-04
  • Mybatis-Plus中Mapper的接口文件與xml文件相關(guān)的坑記錄

    Mybatis-Plus中Mapper的接口文件與xml文件相關(guān)的坑記錄

    這篇文章主要介紹了Mybatis-Plus中Mapper的接口文件與xml文件相關(guān)的坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評(píng)論

扎赉特旗| 奉新县| 安福县| 西青区| 扶余县| 米林县| 安康市| 新津县| 进贤县| 巴彦淖尔市| 林州市| 沙洋县| 彰武县| 白水县| 林周县| 醴陵市| 乌拉特前旗| 磐安县| 洛浦县| 东台市| 山阳县| 香格里拉县| 宁乡县| 临沂市| 中山市| 新泰市| 安岳县| 广南县| 永定县| 神池县| 黔江区| 东至县| 郴州市| 宜兰县| 民丰县| 灌云县| 岳西县| 哈密市| 新余市| 丹巴县| 新营市|