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

當(dāng)前位置:首頁(yè) > 科技  > 軟件

【踩坑指南】線程池使用不當(dāng)?shù)奈鍌€(gè)坑

來(lái)源: 責(zé)編: 時(shí)間:2024-02-04 09:00:55 200觀看
導(dǎo)讀線程池是 Java 多線程編程中的一個(gè)重要概念,它可以有效地管理和復(fù)用線程資源,提高系統(tǒng)的性能和穩(wěn)定性。但是線程池的使用也有一些注意事項(xiàng)和常見(jiàn)的錯(cuò)誤,如果不小心,就可能會(huì)導(dǎo)致一些嚴(yán)重的問(wèn)題,比如內(nèi)存泄漏、死鎖、性能下

線程池是 Java 多線程編程中的一個(gè)重要概念,它可以有效地管理和復(fù)用線程資源,提高系統(tǒng)的性能和穩(wěn)定性。但是線程池的使用也有一些注意事項(xiàng)和常見(jiàn)的錯(cuò)誤,如果不小心,就可能會(huì)導(dǎo)致一些嚴(yán)重的問(wèn)題,比如內(nèi)存泄漏、死鎖、性能下降等。最后文末還有免費(fèi)紅包封面可以領(lǐng)取,回饋給各位讀者朋友。s9p28資訊網(wǎng)——每日最新資訊28at.com

本文將介紹線程池使用不當(dāng)?shù)奈鍌€(gè)坑,以及如何避免和解決它們,大綱如下,s9p28資訊網(wǎng)——每日最新資訊28at.com

圖片s9p28資訊網(wǎng)——每日最新資訊28at.com

坑一:線程池中異常消失

線程池執(zhí)行方法時(shí)要添加異常處理,這是一個(gè)老生常談的問(wèn)題,可是直到最近我都有同事還在犯這個(gè)錯(cuò)誤,所以我還是要講一下,不過(guò)我還提到了一種優(yōu)雅的線程池全局異常處理的方法,大家可以往下看。s9p28資訊網(wǎng)——每日最新資訊28at.com

問(wèn)題原因

@Testpublic void test() throws Exception {    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(        5,         10,         60,        TimeUnit.SECONDS,         new ArrayBlockingQueue<>(100000));    Future<Integer> submit = threadPoolExecutor.execute(() -> {        int i = 1 / 0; // 發(fā)生異常        return i;    });}

如上代碼,在線程池執(zhí)行任務(wù)時(shí),沒(méi)有添加異常處理。導(dǎo)致任務(wù)內(nèi)部發(fā)生異常時(shí),內(nèi)部錯(cuò)誤無(wú)法被記錄下來(lái)。s9p28資訊網(wǎng)——每日最新資訊28at.com

解決方法

在線程池執(zhí)行任務(wù)方法內(nèi)添加 try/catch 處理,代碼如下,s9p28資訊網(wǎng)——每日最新資訊28at.com

@Testpublic void test() throws Exception {    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(        5,         10,         60,        TimeUnit.SECONDS,         new ArrayBlockingQueue<>(100000));    Future<Integer> submit = threadPoolExecutor.execute(() -> {        try {            int i = 1 / 0;            return i;        } catch (Exception e) {            log.error(e.getMessage(), e);            return null;        }    });}

優(yōu)雅的進(jìn)行線程池異常處理

當(dāng)線程池調(diào)用任務(wù)方法很多時(shí),那么每個(gè)線程池任務(wù)執(zhí)行的方法內(nèi)都要添加 try/catch 處理,這就不優(yōu)雅了,其實(shí) ThreadPoolExecutor 線程池類(lèi)支持傳入 ThreadFactory 參數(shù)用于自定義線程工廠,這樣我們?cè)趧?chuàng)建線程時(shí),就可以指定 setUncaughtExceptionHandler 異常處理方法。s9p28資訊網(wǎng)——每日最新資訊28at.com

這樣就可以做到全局處理異常了,代碼如下,s9p28資訊網(wǎng)——每日最新資訊28at.com

ThreadFactory threadFactory = r -> {    Thread thread = new Thread(r);    thread.setUncaughtExceptionHandler((t, e) -> {        // 記錄線程異常        log.error(e.getMessage(), e);    });    return thread;};ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(    5,     10,     60,    TimeUnit.SECONDS,     new ArrayBlockingQueue<>(100000));threadPoolExecutor.execute(() -> {    log.info("---------------------");    int i = 1 / 0;});

不過(guò)要注意的是上面 setUncaughtExceptionHandler 方法只能針對(duì)線程池的 execute 方法來(lái)全局處理異常。對(duì)于線程池的 submit 方法是無(wú)法處理的。s9p28資訊網(wǎng)——每日最新資訊28at.com

坑二:拒絕策略設(shè)置錯(cuò)誤導(dǎo)致接口超時(shí)

在 Java 中,線程池拒絕策略可以說(shuō)一個(gè)常見(jiàn)八股文問(wèn)題。大家雖然都記住了線程池有四種決絕策略,可是實(shí)際代碼編寫(xiě)中,我發(fā)現(xiàn)大多數(shù)人都只會(huì)用 CallerRunsPolicy 策略(由調(diào)用線程處理任務(wù))。我吃過(guò)這個(gè)虧,因此也拿出來(lái)講講。s9p28資訊網(wǎng)——每日最新資訊28at.com

問(wèn)題原因

曾經(jīng)有一個(gè)線上業(yè)務(wù)接口使用了線程池進(jìn)行第三方接口調(diào)用,線程池配置里的拒絕策略采用的是 CallerRunsPolicy。示例代碼如下,s9p28資訊網(wǎng)——每日最新資訊28at.com

// 某個(gè)線上線程池配置如下ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(        50, // 最小核心線程數(shù)        50, // 最大線程數(shù),當(dāng)隊(duì)列滿時(shí),能創(chuàng)建的最大線程數(shù)        60L, TimeUnit.SECONDS, // 空閑線程超過(guò)核心線程時(shí),回收該線程的最大等待時(shí)間        new LinkedBlockingQueue<>(5000), // 阻塞隊(duì)列大小,當(dāng)核心線程使用滿時(shí),新的線程會(huì)放進(jìn)隊(duì)列        new CustomizableThreadFactory("task"), // 自定義線程名        new ThreadPoolExecutor.CallerRunsPolicy() // 線程執(zhí)行的拒絕策略);threadPoolExecutor.execute(() -> {    // 調(diào)用第三方接口    ...});

在第三方接口異常的情況下,線程池任務(wù)調(diào)用第三方接口一直超時(shí),導(dǎo)致核心線程數(shù)、最大線程數(shù)堆積被占滿、阻塞隊(duì)列也被占滿的情況下,也就會(huì)執(zhí)行拒絕策略,但是由于使用的是 CallerRunsPolicy 策略,導(dǎo)致線程任務(wù)直接由我們的業(yè)務(wù)線程來(lái)執(zhí)行。s9p28資訊網(wǎng)——每日最新資訊28at.com

因?yàn)榈谌浇涌诋惓#詷I(yè)務(wù)線程執(zhí)行也會(huì)繼繼續(xù)超時(shí),線上服務(wù)采用的 Tomcat 容器,最終也就導(dǎo)致 Tomcat 的最大線程數(shù)也被占滿,進(jìn)而無(wú)法繼續(xù)向外提供服務(wù)。s9p28資訊網(wǎng)——每日最新資訊28at.com

解決方法

首先我們要考慮業(yè)務(wù)接口的可用性,就算線程池任務(wù)被丟棄,也不應(yīng)該影響業(yè)務(wù)接口。s9p28資訊網(wǎng)——每日最新資訊28at.com

在業(yè)務(wù)接口穩(wěn)定性得到保證的情況下,在考慮到線程池任務(wù)的重要性,不是很重要的話,可以使用 DiscardPolicy 策略直接丟棄,要是很重要,可以考慮使用消息隊(duì)列來(lái)替換線程池。s9p28資訊網(wǎng)——每日最新資訊28at.com

坑三:重復(fù)創(chuàng)建線程池導(dǎo)致內(nèi)存溢出

不知道大家有沒(méi)有犯過(guò)這個(gè)問(wèn)題,不過(guò)我確實(shí)犯過(guò),歸根結(jié)底還是寫(xiě)代碼前,沒(méi)有思考好業(yè)務(wù)邏輯,直接動(dòng)手,寫(xiě)一步算一步

本文鏈接:http://www.www897cc.com/showinfo-26-72429-0.html【踩坑指南】線程池使用不當(dāng)?shù)奈鍌€(gè)坑

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 深入了解Java 8 新特性-日期時(shí)間API之LocalDateTime類(lèi)

下一篇: 什么是數(shù)據(jù)同步利器DataX,如何使用?

標(biāo)簽:
  • 熱門(mén)焦點(diǎn)
Top 主站蜘蛛池模板: 尼木县| 凉城县| 玛多县| 通化县| 无为县| 松桃| 哈巴河县| 宝鸡市| 鹿邑县| 安西县| 金坛市| 侯马市| 宜章县| 延寿县| 泽州县| 九江县| 平谷区| 武胜县| 马边| 汨罗市| 衡东县| 江阴市| 富平县| 石门县| 巴林左旗| 河西区| 通化县| 房产| 浙江省| 隆化县| 沅江市| 阿巴嘎旗| 中卫市| 连江县| 南陵县| 石渠县| 榕江县| 合作市| 五家渠市| 芜湖市| 无为县|