亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

JAVA 線程池的正確打開方式

894974231 / 488人閱讀

摘要:代碼如下是并發(fā)包中提供的,用來快速創(chuàng)建不同類型的線程池。線程池的正確創(chuàng)建方式其實(shí),問題很好解決。總結(jié)最后,我們在使用線程池的時(shí)候,需要根據(jù)使用場景來自行選擇。擴(kuò)展對于一些耗時(shí)的任務(wù),盲目選擇線程池往往不是最佳方案。

JAVA 線程池的正確打開方式
摘要:本文屬于原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請保留出處:https://github.com/jasonGeng88/blog
當(dāng)前環(huán)境

jdk == 1.8

Executors 使用的隱患

先來看一段代碼,我們要?jiǎng)?chuàng)建一個(gè)固定線程池,假設(shè)固定線程數(shù)是4。代碼如下:

Executors是JAVA并發(fā)包中提供的,用來快速創(chuàng)建不同類型的線程池。

是不是很簡單,創(chuàng)建線程池只需一行代碼。對于一些個(gè)人項(xiàng)目或臨時(shí)性的項(xiàng)目,這樣寫確實(shí)沒什么問題,而且開發(fā)速度很快。但在一些大型項(xiàng)目中,這種做法一般是禁止的。

WHY???

因?yàn)橛?b>Executors創(chuàng)建的線程池存在性能隱患,我們看一下源碼就知道,用Executors創(chuàng)建線程池時(shí),使用的隊(duì)列是new LinkedBlockingQueue(),這是一個(gè)無邊界隊(duì)列,如果不斷的往里加任務(wù)時(shí),最終會(huì)導(dǎo)致內(nèi)存問題,也就是說在項(xiàng)目中由于使用了無邊界隊(duì)列,導(dǎo)致的內(nèi)存占用的不可控性。下圖是不斷添加線程任務(wù)導(dǎo)致老年代被占滿的情況:

當(dāng)然,除了內(nèi)存問題,它還存在一些其他的問題,在下面對線程池參數(shù)的介紹中會(huì)具體說明。

線程池的正確創(chuàng)建方式

其實(shí),問題很好解決。提供的簡便方式有局限性,那我們自己new一個(gè)ThreadPoolExecutor,無非多寫幾行代碼而已。

關(guān)于ThreadPoolExecutor的具體代碼如下:

參數(shù)說明:

corePoolSize:核心線程數(shù);

maximumPoolSize:最大線程數(shù),即線程池中允許存在的最大線程數(shù);

keepAliveTime:線程存活時(shí)間,對于超過核心線程數(shù)的線程,當(dāng)線程處理空閑狀態(tài)下,且維持時(shí)間達(dá)到keepAliveTime時(shí),線程將被銷毀;

unit:keepAliveTime的時(shí)間單位

workQueue:工作隊(duì)列,用于存在待執(zhí)行的線程任務(wù);

threadFactory:創(chuàng)建線程的工廠,用于標(biāo)記區(qū)分不同線程池所創(chuàng)建出來的線程;

handler:當(dāng)?shù)竭_(dá)線程數(shù)上限或工作隊(duì)列已滿時(shí)的拒絕處理邏輯;

具體代碼

自定義threadFactory。除了可以自定義創(chuàng)建的線程名稱,方便問題排查,在newThread(Runnable r)創(chuàng)建線程的方法中,還可以進(jìn)行定制化設(shè)置,如為線程設(shè)置特定上下文等。

自定義RejectedExecutionHandler。記錄異常信息,選擇不同處理邏輯,有交由當(dāng)前線程執(zhí)行任務(wù),有直接拋出異常,再或者等待后繼續(xù)添加任務(wù)等。

創(chuàng)建自定義線程池

線程池內(nèi)在處理邏輯

我們通過一些例子,來觀察一下其內(nèi)部的處理邏輯?;谏鲜鼍唧w代碼,我們已經(jīng)創(chuàng)建了一個(gè)核心線程數(shù)4,最大線程數(shù)8,線程存活時(shí)間10s,工作隊(duì)列最大容量為10的一個(gè)線程池。

初始化線程池:未添加線程任務(wù)

這時(shí),線程池中不會(huì)創(chuàng)建任何線程,存活線程為0,工作隊(duì)列為0.

未達(dá)核心線程數(shù):添加4個(gè)線程任務(wù)

由于當(dāng)前存活線程數(shù) <= 核心線程數(shù),所以會(huì)創(chuàng)建新的線程。即存活線程為4,工作隊(duì)列為0.

核心線程數(shù)已滿:添加第5個(gè)線程任務(wù)

若當(dāng)前線程池中存在空閑線程,則交由該線程處理。即存活線程為4,工作隊(duì)列為0.

若當(dāng)前所有線程處理運(yùn)行狀態(tài),加入工作隊(duì)列。即存活線程為4,工作隊(duì)列為1.(注意:此時(shí)工作隊(duì)列中的任務(wù)不會(huì)被執(zhí)行,直到有線程空閑后,才能被處理

工作隊(duì)列未滿:假設(shè)添加的任務(wù)都是耗時(shí)操作(短時(shí)間不會(huì)結(jié)束),再添加9個(gè)耗時(shí)任務(wù)

即存活線程為4,工作隊(duì)列為10.

工作隊(duì)列已滿 & 未達(dá)最大線程數(shù):再添加4個(gè)任務(wù)

當(dāng)工作隊(duì)列已滿,且不存在空閑線程,此時(shí)會(huì)創(chuàng)建額外線程來處理當(dāng)前任務(wù)。此時(shí)存活線程為8,工作隊(duì)列為10.

工作隊(duì)列已滿 & 且最大線程數(shù)已滿:再添加1個(gè)任務(wù)

觸發(fā)RejectedExecutionHandler,將當(dāng)前任務(wù)交由自己設(shè)置的執(zhí)行句柄進(jìn)行處理。此時(shí)存活線程為8,工作隊(duì)列為10.

當(dāng)任務(wù)執(zhí)行完后,沒有新增的任務(wù),臨時(shí)擴(kuò)充的線程(大于核心線程數(shù)的)將在10s(keepAliveTime)后被銷毀。

總結(jié)

最后,我們在使用線程池的時(shí)候,需要根據(jù)使用場景來自行選擇。通過corePoolSize和maximumPoolSize的搭配,存活時(shí)間的選擇,以及改變隊(duì)列的實(shí)現(xiàn)方式,如:選擇延遲隊(duì)列,來實(shí)現(xiàn)定時(shí)任務(wù)的功能。并發(fā)包Executors中提供的一些方法確實(shí)好用,但我們?nèi)孕栌斜A舻厝ナ褂茫@樣在項(xiàng)目中就不會(huì)挖太多的坑。

擴(kuò)展

對于一些耗時(shí)的IO任務(wù),盲目選擇線程池往往不是最佳方案。通過異步+單線程輪詢,上層再配合上一個(gè)固定的線程池,效果可能更好。類似與Reactor模型中selector輪詢處理

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/76315.html

相關(guān)文章

  • 技術(shù)經(jīng)理:求求你,別再亂改數(shù)據(jù)庫連接池的大小了!

    摘要:你僅僅需要一個(gè)大小為數(shù)據(jù)庫連接池,然后讓剩下的業(yè)務(wù)線程都在隊(duì)列里等待就可以了。你應(yīng)該經(jīng)常會(huì)看到一些用戶量不是很大的應(yīng)用中,為應(yīng)付大約十來個(gè)的并發(fā),卻將數(shù)據(jù)庫連接池設(shè)置成,的情況。請不要過度配置您的數(shù)據(jù)庫連接池的大小。 文章翻譯整理自: https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing歡迎關(guān)注個(gè)人微信公眾...

    darkbug 評論0 收藏0
  • 技術(shù)經(jīng)理:求求你,別再亂改數(shù)據(jù)庫連接池的大小了!

    摘要:你僅僅需要一個(gè)大小為數(shù)據(jù)庫連接池,然后讓剩下的業(yè)務(wù)線程都在隊(duì)列里等待就可以了。你應(yīng)該經(jīng)常會(huì)看到一些用戶量不是很大的應(yīng)用中,為應(yīng)付大約十來個(gè)的并發(fā),卻將數(shù)據(jù)庫連接池設(shè)置成,的情況。請不要過度配置您的數(shù)據(jù)庫連接池的大小。 文章翻譯整理自: https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing歡迎關(guān)注個(gè)人微信公眾...

    蘇丹 評論0 收藏0
  • Java 線程池詳解

    摘要:最近項(xiàng)目中越來越多需要異步調(diào)用的地方,系統(tǒng)中雖有線程池管理,但還有可優(yōu)化的空間,通過分享該文章,幫助大家了解線程池,同時(shí)學(xué)習(xí)使用線程池開啟線程需要注意的地方。沒錯(cuò),上述方法創(chuàng)建的線程池就是。線程池就是程序中的裝修公司,代勞各種臟活累活。 最近項(xiàng)目中越來越多需要異步調(diào)用的地方,系統(tǒng)中雖有線程池管理,但還有可優(yōu)化的空間,通過分享該文章,幫助大家了解線程池,同時(shí)學(xué)習(xí)使用線程池開啟線程需要注意...

    fanux 評論0 收藏0
  • Java線程池簡單總結(jié)

    摘要:本文主要內(nèi)容為簡單總結(jié)中線程池的相關(guān)信息。方法簇方法簇用于創(chuàng)建固定線程數(shù)的線程池。三種常見線程池的對比上文總結(jié)了工具類創(chuàng)建常見線程池的方法,現(xiàn)對三種線程池區(qū)別進(jìn)行比較。 概述 線程可認(rèn)為是操作系統(tǒng)可調(diào)度的最小的程序執(zhí)行序列,一般作為進(jìn)程的組成部分,同一進(jìn)程中多個(gè)線程可共享該進(jìn)程的資源(如內(nèi)存等)。在單核處理器架構(gòu)下,操作系統(tǒng)一般使用分時(shí)的方式實(shí)現(xiàn)多線程;在多核處理器架構(gòu)下,多個(gè)線程能夠...

    CoorChice 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<