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

Java的ThreadPoolExecutor業(yè)務(wù)線程池詳細(xì)解析

 更新時(shí)間:2024年01月18日 10:39:15   作者:岸河  
這篇文章主要介紹了Java線程池ThreadPoolExecutor詳細(xì)解析,任務(wù)剛開始進(jìn)來的時(shí)候就創(chuàng)建核心線程,核心線程滿了會把任務(wù)放到阻塞隊(duì)列,阻塞隊(duì)列滿了之后才會創(chuàng)建空閑線程,達(dá)到最大線程數(shù)之后,再有任務(wù)進(jìn)來,就只能執(zhí)行拒絕策略了,需要的朋友可以參考下

ThreadPoolExecutor業(yè)務(wù)線程池

1.什么是業(yè)務(wù)線程池?

在業(yè)務(wù)開發(fā)中,用來處理業(yè)務(wù)的線程池。

2.為什么需要業(yè)務(wù)線程池?

大多數(shù)同學(xué)都是做業(yè)務(wù)開發(fā)的,很多業(yè)務(wù)的操作并非要求一定是同步的。例如,對于一系列連續(xù)的業(yè)務(wù)邏輯處理,很多都是數(shù)據(jù)的組裝,拼接,查詢,或者將數(shù)據(jù)同步給各個(gè)下層業(yè)務(wù)(對事務(wù)性沒有嚴(yán)格要求);或者對數(shù)據(jù)的批量操作;這些都可以是異步的。通常業(yè)務(wù)項(xiàng)目使用的都是的servlet框架,都是使用一個(gè)線程進(jìn)行業(yè)務(wù)邏輯處理,這種模型是通用的,但不一定是最佳的,不一定是最適合的。需要我們業(yè)務(wù)開發(fā)者根據(jù)實(shí)際的業(yè)務(wù)場景去靈活應(yīng)用,達(dá)到最快的響應(yīng),最大的吞吐量。

3.業(yè)務(wù)線程池應(yīng)用的思路是來自哪里?

個(gè)人理解,來自于開源框架。各種池化的概念,太多了,線程池,內(nèi)存池,實(shí)例池,連接池。太多框架使用了線程池的概念,spring,tomcat,dubbo,netty,rocketmq,nacos,druid,總而言之,幾乎所有的框架,都用到了線程池。雖然他們是框架線程池,但是抽出來想一下,對于框架線程池來講,我們對于框架的使用,也是業(yè)務(wù)流程,也需要業(yè)務(wù)邏輯的處理,因此,業(yè)務(wù)線程池,框架線程池,兩者并無區(qū)別。

一、業(yè)務(wù)線程池的好處

這里借用《Java 并發(fā)編程的藝術(shù)》提到的來說一下使用線程池的好處:

  • 降低資源消耗。通過重復(fù)利用已創(chuàng)建的線程降低線程創(chuàng)建和銷毀造成的消耗。
  • 提高響應(yīng)速度。當(dāng)任務(wù)到達(dá)時(shí),任務(wù)可以不需要的等到線程創(chuàng)建就能立即執(zhí)行。
  • 提高線程的可管理性。線程是稀缺資源,如果無限制的創(chuàng)建,不僅會消耗系統(tǒng)資源,還會降低系統(tǒng)的穩(wěn)定性,使用線程池可以進(jìn)行統(tǒng)一的分配,調(diào)優(yōu)和監(jiān)控。

二、線程池基本認(rèn)識

參數(shù)說明

/**
 * 用給定的初始參數(shù)創(chuàng)建一個(gè)新的ThreadPoolExecutor。
 */
public ThreadPoolExecutor(int corePoolSize,//線程池的核心線程數(shù)量
                          int maximumPoolSize,//線程池的最大線程數(shù)
                          long keepAliveTime,//當(dāng)線程數(shù)大于核心線程數(shù)時(shí),多余的空閑線程存活的最長時(shí)間
                          TimeUnit unit,//時(shí)間單位
                          BlockingQueue<Runnable> workQueue,//任務(wù)隊(duì)列,用來儲存等待執(zhí)行任務(wù)的隊(duì)列
                          ThreadFactory threadFactory,//線程工廠,用來創(chuàng)建線程,一般默認(rèn)即可
                          RejectedExecutionHandler handler//拒絕策略,當(dāng)提交的任務(wù)過多而不能及時(shí)處理時(shí),我們可以定制策略來處理任務(wù)
                           ) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

拒絕策略

  • AbortPolicy:直接拋出異常,這是默認(rèn)策略;
  • CallerRunsPolicy:用調(diào)用者所在的線程來執(zhí)行任務(wù);(這種場景下,可以保證數(shù)據(jù)不丟失,但是會阻塞主線程)
  • DiscardOldestPolicy:丟棄阻塞隊(duì)列中靠最前的任務(wù),并執(zhí)行當(dāng)前任務(wù);
  • DiscardPolicy:直接丟棄任務(wù);

ExecutorService 中 shutdown()、shutdownNow()、awaitTermination() 含義和區(qū)別

  • shutdown():停止接收新任務(wù),原來的任務(wù)繼續(xù)執(zhí)行
  • shutdownNow():停止接收新任務(wù),原來的任務(wù)停止執(zhí)行
  • awaitTermination(long timeOut, TimeUnit unit):當(dāng)前線程阻塞

注意:

awaitTermination一般是配合shutdown使用。

ThreadPoolExecutor運(yùn)行狀態(tài)

ThreadPoolExecutor類中定義了5個(gè)Integer常量,狀態(tài)分別為

// runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    private static final int STOP       =  1 << COUNT_BITS;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;

在這里插入圖片描述

經(jīng)典面試題

線程池什么時(shí)候創(chuàng)建核心線程,什么時(shí)候把任務(wù)放進(jìn)阻塞隊(duì)列,什么時(shí)候創(chuàng)建空閑線程?

答:任務(wù)剛開始進(jìn)來的時(shí)候就創(chuàng)建核心線程,核心線程滿了會把任務(wù)放到阻塞隊(duì)列,阻塞隊(duì)列滿了之后才會創(chuàng)建空閑線程,達(dá)到最大線程數(shù)之后,再有任務(wù)進(jìn)來,就只能執(zhí)行拒絕策略了。

注意,執(zhí)行拒絕策略有兩個(gè)場景,一個(gè)是空閑線程也滿了,二是線程池不在運(yùn)行了,比如執(zhí)行了shutdown的方法,但是這個(gè)時(shí)候又來了新任務(wù)。

在這里插入圖片描述

基礎(chǔ)知識

現(xiàn)阻塞隊(duì)列的接口是BlockingQueue,jdk1.5新增的,在juc包下面,作者是Doug Lea,它的父接口是Queue,也是jdk1.5新增的,在java.util包下面,屬于集合類,作者還是Doug Lea。

三、線程池最佳實(shí)踐

1.打印線程池的狀態(tài),關(guān)注線程池運(yùn)行情況(個(gè)人非常喜歡)

/**
     * 打印線程池的狀態(tài)
     *
     * @param threadPool 線程池對象
     */
    public static void printThreadPoolStatus(ThreadPoolExecutor threadPool) {
        ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1, createThreadFactory("print-thread-pool-status", false));
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            log.info("=========================");
            log.info("ThreadPool Size: [{}]", threadPool.getPoolSize());
            log.info("Active Threads: {}", threadPool.getActiveCount());
            log.info("Number of Tasks : {}", threadPool.getCompletedTaskCount());
            log.info("Number of Tasks in Queue: {}", threadPool.getQueue().size());
            log.info("=========================");
        }, 0, 1, TimeUnit.SECONDS);
    }

2.不同業(yè)務(wù)使用不同的業(yè)務(wù)線程池

父子任務(wù)也不要使用一個(gè)線程池(會發(fā)生死鎖),死鎖原因:父任務(wù)占用了所有的核心線程,自子任務(wù)在阻塞隊(duì)列里等待父任務(wù)釋放核心線程,父線程等待子任務(wù)完成任務(wù)。

3.為什么不能使用原生的Executors工具創(chuàng)建線程池

阻塞隊(duì)列都是Integer.MAX,容易發(fā)生OOM,而且無線程池命名,沒有關(guān)心空閑時(shí)間,拒絕策略,太粗糙了,除非你不關(guān)心業(yè)務(wù)。

4.如果設(shè)置線程數(shù)量?

有一個(gè)簡單并且適用面比較廣的公式:

  • CPU 密集型任務(wù)(N+1): 這種任務(wù)消耗的主要是 CPU 資源,可以將線程數(shù)設(shè)置為 N(CPU 核心數(shù))+1,比 CPU 核心數(shù)多出來的一個(gè)線程是為了防止線程偶發(fā)的缺頁中斷,或者其它原因?qū)е碌娜蝿?wù)暫停而帶來的影響。一旦任務(wù)暫停,CPU 就會處于空閑狀態(tài),而在這種情況下多出來的一個(gè)線程就可以充分利用 CPU 的空閑時(shí)間。
  • I/O 密集型任務(wù)(2N): 這種任務(wù)應(yīng)用起來,系統(tǒng)會用大部分的時(shí)間來處理 I/O 交互,而線程在處理 I/O 的時(shí)間段內(nèi)不會占用 CPU 來處理,這時(shí)就可以將 CPU 交出給其它線程使用。因此在 I/O 密集型任務(wù)的應(yīng)用中,我們可以多配置一些線程,具體的計(jì)算方法是 2N。

5.[美團(tuán)] Java線程池實(shí)現(xiàn)原理及其在美團(tuán)業(yè)務(wù)中的實(shí)踐

由于隊(duì)列設(shè)置過長,最大線程數(shù)設(shè)置失效,導(dǎo)致請求數(shù)量增加時(shí),大量任務(wù)堆積在隊(duì)列中,任務(wù)執(zhí)行時(shí)間過長,最終導(dǎo)致下游服務(wù)的大量調(diào)用超時(shí)失敗。

ThreadPoolExecutor的corePoolSize的值是可以設(shè)置的。利用這點(diǎn)加上配置中心,可以動態(tài)的調(diào)整核心線程數(shù)。

四、線程池總結(jié)

做好業(yè)務(wù)線程池,分三個(gè)級別

第一級別,根據(jù)業(yè)務(wù)特性實(shí)現(xiàn)不同的業(yè)務(wù)線程池。

第二級別,根據(jù)業(yè)務(wù)特性,動態(tài)調(diào)整線程池配置。

第三級別,實(shí)時(shí)監(jiān)控與配置線程池運(yùn)行情況。

到此這篇關(guān)于Java的ThreadPoolExecutor業(yè)務(wù)線程池詳細(xì)解析的文章就介紹到這了,更多相關(guān)ThreadPoolExecutor業(yè)務(wù)線程池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決Feign配置RequestContextHolder.getRequestAttributes()為null的問題

    解決Feign配置RequestContextHolder.getRequestAttributes()為null的問題

    這篇文章主要介紹了解決Feign配置RequestContextHolder.getRequestAttributes()為null的問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • mvn compile報(bào)錯(cuò)“程序包c(diǎn)om.XXX不存在”

    mvn compile報(bào)錯(cuò)“程序包c(diǎn)om.XXX不存在”

    本文主要介紹了mvn compile報(bào)錯(cuò)“程序包c(diǎn)om.XXX不存在”,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Spring通過ApplicationContext主動獲取bean的方法講解

    Spring通過ApplicationContext主動獲取bean的方法講解

    今天小編就為大家分享一篇關(guān)于Spring通過ApplicationContext主動獲取bean的方法講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 解決Maven本地倉庫明明有對應(yīng)的jar包但還是報(bào)找不到的問題

    解決Maven本地倉庫明明有對應(yīng)的jar包但還是報(bào)找不到的問題

    這篇文章主要介紹了解決Maven本地倉庫明明有對應(yīng)的jar包但還是報(bào)找不到的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • mybatis-plus配置攔截器實(shí)現(xiàn)sql完整打印的代碼設(shè)計(jì)

    mybatis-plus配置攔截器實(shí)現(xiàn)sql完整打印的代碼設(shè)計(jì)

    在使用mybatis-plus(mybatis)的時(shí)候,往往需要打印完整的sql語句,然而輸出的日志不是很理想,因?yàn)閟ql語句中的關(guān)鍵字段信息都是用?來代替的,所以本文分享了一下自己寫了一個(gè)攔截器實(shí)現(xiàn)了sql完整的打印,需要的朋友可以參考下
    2024-06-06
  • 初探Spring Cloud Gateway實(shí)戰(zhàn)

    初探Spring Cloud Gateway實(shí)戰(zhàn)

    這篇文章主要介紹了創(chuàng)建網(wǎng)關(guān)項(xiàng)目(Spring Cloud Gateway)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-08-08
  • java實(shí)現(xiàn)數(shù)字猜拳小游戲

    java實(shí)現(xiàn)數(shù)字猜拳小游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)數(shù)字猜拳的小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • Spring運(yùn)行時(shí)手動注入bean的方法實(shí)例

    Spring運(yùn)行時(shí)手動注入bean的方法實(shí)例

    spring給我們提供了IOC服務(wù),讓我們可以用注解的方式,方便的使用bean的相互引用,下面這篇文章主要給大家介紹了關(guān)于Spring運(yùn)行時(shí)手動注入bean的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • MyBatis-Plus詳解(環(huán)境搭建、關(guān)聯(lián)操作)

    MyBatis-Plus詳解(環(huán)境搭建、關(guān)聯(lián)操作)

    MyBatis-Plus 是一個(gè) MyBatis 的增強(qiáng)工具,在 MyBatis 的基礎(chǔ)上只做增強(qiáng)不做改變,為簡化開發(fā)、提高效率而生,今天通過本文給大家介紹MyBatis-Plus環(huán)境搭建及關(guān)聯(lián)操作,需要的朋友參考下吧
    2022-09-09
  • IDEA .iml文件及.idea文件夾超詳細(xì)講解

    IDEA .iml文件及.idea文件夾超詳細(xì)講解

    iml文件是IntelliJ IDEA自己創(chuàng)建的模塊文件,用于java應(yīng)用開發(fā),存儲一些模塊相關(guān)的信息,比如一個(gè)Java組建,插件組建,Maven組建等,這篇文章主要介紹了IDEA .iml文件及.idea文件夾,需要的朋友可以參考下
    2023-09-09

最新評論

曲水县| 綦江县| 鹤岗市| 江孜县| 岐山县| 镇赉县| 焦作市| 行唐县| 斗六市| 阿克陶县| 昆明市| 北川| 舟山市| 铅山县| 庄河市| 和龙市| 全州县| 屏山县| 望城县| 保德县| 峨山| 峨边| 南雄市| 宣恩县| 靖江市| 嵩明县| 二连浩特市| 阳城县| 嘉义县| 平度市| 乌鲁木齐县| 曲麻莱县| 大埔县| 高邑县| 无锡市| 四子王旗| 永胜县| 磐石市| 永康市| 上饶市| 乐山市|