亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java線程池必知必會(huì)知識(shí)點(diǎn)總結(jié)

 更新時(shí)間:2022年02月18日 16:37:40   作者:ForeverKobe  
這篇文章主要給大家介紹了關(guān)于Java線程池必知必會(huì)知識(shí)點(diǎn)的相關(guān)資料,文中通過(guò)圖文以及實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

1、線程數(shù)使用開發(fā)規(guī)約

阿里巴巴開發(fā)手冊(cè)中關(guān)于線程和線程池的使用有如下三條強(qiáng)制規(guī)約

【強(qiáng)制】創(chuàng)建線程或線程池時(shí)請(qǐng)指定有意義的線程名稱,方便出錯(cuò)時(shí)回溯。

正例:自定義線程工廠,并且根據(jù)外部特征進(jìn)行分組,比如,來(lái)自同一機(jī)房的調(diào)用,把機(jī)房編號(hào)賦值給whatFeatureOfGroup

public class UserThreadFactory implements ThreadFactory {
private final String namePrefix;
private final AtomicInteger nextId = new AtomicInteger(1);
/**
* 定義線程組名稱,在利用 jstack 來(lái)排查問(wèn)題時(shí),非常有幫助
*/

UserThreadFactory(String whatFeatureOfGroup) {
namePrefix = "From UserThreadFactory's " + whatFeatureOfGroup + "-Worker-";
}

@Override
public Thread newThread(Runnable task) {
String name = namePrefix + nextId.getAndIncrement();
Thread thread = new Thread(null, task, name, 0);
System.out.println(thread.getName());
return thread;
}
}

【強(qiáng)制】線程資源必須通過(guò)線程池提供,不允許在應(yīng)用中自行顯式創(chuàng)建線程。

說(shuō)明:線程池的好處是減少在創(chuàng)建和銷毀線程上所消耗的時(shí)間以及系統(tǒng)資源的開銷,解決資源不足的問(wèn)題。

如果不使用線程池,有可能造成系統(tǒng)創(chuàng)建大量同類線程而導(dǎo)致消耗完內(nèi)存或者“過(guò)度切換”的問(wèn)題。

【強(qiáng)制】線程池不允許使用 Executors 去創(chuàng)建,而是通過(guò) ThreadPoolExecutor 的方式,這

樣的處理方式讓寫的同學(xué)更加明確線程池的運(yùn)行規(guī)則,規(guī)避資源耗盡的風(fēng)險(xiǎn)。

說(shuō)明:Executors 返回的線程池對(duì)象的弊端如下:

1) FixedThreadPool 和 SingleThreadPool:

允許的請(qǐng)求隊(duì)列長(zhǎng)度為 Integer.MAX_VALUE,可能會(huì)堆積大量的請(qǐng)求,從而導(dǎo)致 OOM。

2) CachedThreadPool:

允許的創(chuàng)建線程數(shù)量為 Integer.MAX_VALUE,可能會(huì)創(chuàng)建大量的線程,從而導(dǎo)致 OOM。

2、 ThreadPoolExecutor源碼

1. 構(gòu)造函數(shù)

UML圖:

ThreadPoolExecutor的構(gòu)造函數(shù)共有四個(gè),但最終調(diào)用的都是同一個(gè):

2.核心參數(shù)

  • corePoolSize => 線程池核心線程數(shù)量

  • maximumPoolSize => 線程池最大數(shù)量

  • keepAliveTime => 線程池的工作線程空閑后,保持存活的時(shí)間。如果任務(wù)多而且任務(wù)的執(zhí)行時(shí)間比較短,可以調(diào)大keepAliveTime,提高線程的利用率。

  • unit => 時(shí)間單位

  • workQueue => 線程池所使用的緩沖隊(duì)列,隊(duì)列類型有:

    • ArrayBlockingQueue,基于數(shù)組結(jié)構(gòu)的有界阻塞隊(duì)列,按FIFO(先進(jìn)先出)原則對(duì)任務(wù)進(jìn)行排序。使用該隊(duì)列,線程池中能創(chuàng)建的最大線程數(shù)為maximumPoolSize

    • LinkedBlockingQueue,基于鏈表結(jié)構(gòu)的無(wú)界阻塞隊(duì)列,按FIFO(先進(jìn)先出)原則對(duì)任務(wù)進(jìn)行排序,吞吐量高于ArrayBlockingQueue。使用該隊(duì)列,線程池中能創(chuàng)建的最大線程數(shù)為corePoolSize。靜態(tài)工廠方法 Executor.newFixedThreadPool()使用了這個(gè)隊(duì)列。

    • SynchronousQueue,一個(gè)不存儲(chǔ)元素的阻塞隊(duì)列。添加任務(wù)的操作必須等到另一個(gè)線程的移除操作,否則添加操作一直處于阻塞狀態(tài)。靜態(tài)工廠方法 Executor.newCachedThreadPool()使用了這個(gè)隊(duì)列。

    • PriorityBlokingQueue:一個(gè)支持優(yōu)先級(jí)的無(wú)界阻塞隊(duì)列。使用該隊(duì)列,線程池中能創(chuàng)建的最大線程數(shù)為corePoolSize。

  • threadFactory => 線程池創(chuàng)建線程使用的工廠

  • handler => 線程池對(duì)拒絕任務(wù)的處理策略,主要有4種類型的拒絕策略:

    • AbortPolicy:無(wú)法處理新任務(wù)時(shí),直接拋出異常,這是默認(rèn)策略。

    • CallerRunsPolicy:用調(diào)用者所在的線程來(lái)執(zhí)行任務(wù)。

    • DiscardOldestPolicy:丟棄阻塞隊(duì)列中最靠前的一個(gè)任務(wù),并執(zhí)行當(dāng)前任務(wù)。

    • DiscardPolicy:直接丟棄任務(wù)。

3.execute()方法

  • 如果當(dāng)前運(yùn)行的線程少于corePoolSize,則創(chuàng)建新的工作線程來(lái)執(zhí)行任務(wù)(執(zhí)行這一步驟需要獲取全局鎖)。

  • 如果當(dāng)前運(yùn)行的線程大于或等于corePoolSize,而且BlockingQueue未滿,則將任務(wù)加入到BlockingQueue中。

  • 如果BlockingQueue已滿,而且當(dāng)前運(yùn)行的線程小于maximumPoolSize,則創(chuàng)建新的工作線程來(lái)執(zhí)行任務(wù)(執(zhí)行這一步驟需要獲取全局鎖)。

  • 如果當(dāng)前運(yùn)行的線程大于或等于maximumPoolSize,任務(wù)將被拒絕,并調(diào)用RejectExecutionHandler.rejectExecution()方法。即調(diào)用飽和策略對(duì)任務(wù)進(jìn)行處理。

3、線程池的工作流程

執(zhí)行邏輯說(shuō)明:

  • 判斷核心線程數(shù)是否已滿,核心線程數(shù)大小和corePoolSize參數(shù)有關(guān),未滿則創(chuàng)建線程執(zhí)行任務(wù)

  • 若核心線程池已滿,判斷隊(duì)列是否滿,隊(duì)列是否滿和workQueue參數(shù)有關(guān),若未滿則加入隊(duì)列中

  • 若隊(duì)列已滿,判斷線程池是否已滿,線程池是否已滿和maximumPoolSize參數(shù)有關(guān),若未滿創(chuàng)建線程執(zhí)行任務(wù)

  • 若線程池已滿,則采用拒絕策略處理無(wú)法執(zhí)執(zhí)行的任務(wù),拒絕策略和handler參數(shù)有關(guān)

4、Executors創(chuàng)建返回ThreadPoolExecutor對(duì)象(不推薦)

Executors創(chuàng)建返回ThreadPoolExecutor對(duì)象的方法共有三種:

1. Executors#newCachedThreadPool => 創(chuàng)建可緩存的線程池

  • corePoolSize => 0,核心線程池的數(shù)量為0

  • maximumPoolSize => Integer.MAX_VALUE,可以認(rèn)為最大線程數(shù)是無(wú)限的

  • keepAliveTime => 60L

  • unit => 秒

  • workQueue => SynchronousQueue

弊端:maximumPoolSize => Integer.MAX_VALUE可能會(huì)導(dǎo)致OOM

2. Executors#newSingleThreadExecutor => 創(chuàng)建單線程的線程池

SingleThreadExecutor是單線程線程池,只有一個(gè)核心線程:

  • corePoolSize => 1,核心線程池的數(shù)量為1

  • maximumPoolSize => 1,只可以創(chuàng)建一個(gè)非核心線程

  • keepAliveTime => 0L

  • unit => 毫秒

  • workQueue => LinkedBlockingQueue

弊端:LinkedBlockingQueue是長(zhǎng)度為Integer.MAX_VALUE的隊(duì)列,可以認(rèn)為是無(wú)界隊(duì)列,因此往隊(duì)列中可以插入無(wú)限多的任務(wù),在資源有限的時(shí)候容易引起OOM異常

3. Executors#newFixedThreadPool => 創(chuàng)建固定長(zhǎng)度的線程池

  • corePoolSize => 1,核心線程池的數(shù)量為1

  • maximumPoolSize => 1,只可以創(chuàng)建一個(gè)非核心線程

  • keepAliveTime => 0L

  • unit => 毫秒

  • workQueue => LinkedBlockingQueue

它和SingleThreadExecutor類似,唯一的區(qū)別就是核心線程數(shù)不同,并且由于使用的是LinkedBlockingQueue,在資源有限的時(shí)候容易引起OOM異常

5、線程池的合理配置

從以下幾個(gè)角度分析任務(wù)的特性:

  • 任務(wù)的性質(zhì):CPU 密集型任務(wù)、IO 密集型任務(wù)和混合型任務(wù)。

  • 任務(wù)的優(yōu)先級(jí):高、中、低。

  • 任務(wù)的執(zhí)行時(shí)間:長(zhǎng)、中、短。

  • 任務(wù)的依賴性:是否依賴其他系統(tǒng)資源,如數(shù)據(jù)庫(kù)連接。

任務(wù)性質(zhì)不同的任務(wù)可以用不同規(guī)模的線程池分開處理??梢酝ㄟ^(guò) Runtime.getRuntime().availableProcessors()方法獲得當(dāng)前設(shè)備的 CPU 個(gè)數(shù)。

  • CPU 密集型任務(wù):配置盡可能小的線程,如配置 cpu核心數(shù)+1 個(gè)線程的線程池。

  • IO 密集型任務(wù) :由于線程并不是一直在執(zhí)行任務(wù),則配置盡可能多的線程,如2 ∗ Ncpu。

  • 混合型任務(wù):如果可以拆分,則將其拆分成一個(gè) CPU 密集型任務(wù)和一個(gè) IO 密集型任務(wù)。只要這兩個(gè)任務(wù)執(zhí)行的時(shí)間相差不是太大,那么分解后執(zhí)行的吞吐率要高于串行執(zhí)行的吞吐率;如果這兩個(gè)任務(wù)執(zhí)行時(shí)間相差太大,則沒(méi)必要進(jìn)行分解。

優(yōu)先級(jí)不同的任務(wù)可以使用優(yōu)先級(jí)隊(duì)列 PriorityBlockingQueue 來(lái)處理,它可以讓優(yōu)先級(jí)高的任務(wù)先得到執(zhí)行。但是,如果一直有高優(yōu)先級(jí)的任務(wù)加入到阻塞隊(duì)列中,那么低優(yōu)先級(jí)的任務(wù)可能永遠(yuǎn)不能執(zhí)行。

執(zhí)行時(shí)間不同的任務(wù)可以交給不同規(guī)模的線程池來(lái)處理,或者也可以使用優(yōu)先級(jí)隊(duì)列,讓執(zhí)行時(shí)間短的任務(wù)先執(zhí)行。

依賴數(shù)據(jù)庫(kù)連接池的任務(wù),因?yàn)榫€程提交 SQL 后需要等待數(shù)據(jù)庫(kù)返回結(jié)果,線程數(shù)應(yīng)該設(shè)置得較大,這樣才能更好的利用 CPU。

建議使用有界隊(duì)列,有界隊(duì)列能增加系統(tǒng)的穩(wěn)定性和預(yù)警能力。可以根據(jù)需要設(shè)大一點(diǎn),比如幾千。使用無(wú)界隊(duì)列,線程池的隊(duì)列就會(huì)越來(lái)越大,有可能會(huì)撐滿內(nèi)存,導(dǎo)致整個(gè)系統(tǒng)不可用。

處理拒絕策略有以下幾種比較推薦:

在程序中捕獲RejectedExecutionException異常,在捕獲異常中對(duì)任務(wù)進(jìn)行處理。針對(duì)默認(rèn)拒絕策略使用CallerRunsPolicy拒絕策略,該策略會(huì)將任務(wù)交給調(diào)用execute的線程執(zhí)行【一般為主線程】,此時(shí)主線程將在一段時(shí)間內(nèi)不能提交任何任務(wù),從而使工作線程處理正在執(zhí)行的任務(wù)。此時(shí)提交的線程將被保存在TCP隊(duì)列中,TCP隊(duì)列滿將會(huì)影響客戶端,這是一種平緩的性能降低自定義拒絕策略,只需要實(shí)現(xiàn)RejectedExecutionHandler接口即可如果任務(wù)不是特別重要,使用DiscardPolicy和DiscardOldestPolicy拒絕策略將任務(wù)丟棄也是可以的如果使用Executors的靜態(tài)方法創(chuàng)建ThreadPoolExecutor對(duì)象,可以通過(guò)使用Semaphore對(duì)任務(wù)的執(zhí)行進(jìn)行限流也可以避免出現(xiàn)OOM異常。

6、拒絕策略

有以下幾種比較推薦:

  • 在程序中捕獲RejectedExecutionException異常,在捕獲異常中對(duì)任務(wù)進(jìn)行處理。針對(duì)默認(rèn)拒絕策略

  • 使用CallerRunsPolicy拒絕策略,該策略會(huì)將任務(wù)交給調(diào)用execute的線程執(zhí)行【一般為主線程】,此時(shí)主線程將在一段時(shí)間內(nèi)不能提交任何任務(wù),從而使工作線程處理正在執(zhí)行的任務(wù)。此時(shí)提交的線程將被保存在TCP隊(duì)列中,TCP隊(duì)列滿將會(huì)影響客戶端,這是一種平緩的性能降低

  • 自定義拒絕策略,只需要實(shí)現(xiàn)RejectedExecutionHandler接口即可

  • 如果任務(wù)不是特別重要,使用DiscardPolicy和DiscardOldestPolicy拒絕策略將任務(wù)丟棄也是可以的如果使用Executors的靜態(tài)方法創(chuàng)建ThreadPoolExecutor對(duì)象,可以通過(guò)使用Semaphore對(duì)任務(wù)的執(zhí)行進(jìn)行限流也可以避免出現(xiàn)OOM異常。

  • 參考文章:8大拒絕策略

7、線程池的五種運(yùn)行狀態(tài)

線程狀態(tài):

不同于線程狀態(tài),線程池也有如下幾種 狀態(tài):

RUNNING :該狀態(tài)的線程池既能接受新提交的任務(wù),又能處理阻塞隊(duì)列中任務(wù)。

SHUTDOWN:該狀態(tài)的線程池不能接收新提交的任務(wù),但是能處理阻塞隊(duì)列中的任務(wù)。(政府服務(wù)大廳不在允許群眾拿號(hào)了,處理完手頭的和排隊(duì)的政務(wù)就下班)

處于 RUNNING 狀態(tài)時(shí),調(diào)用 shutdown()方法會(huì)使線程池進(jìn)入到該狀態(tài)。

注意:finalize() 方法在執(zhí)行過(guò)程中也會(huì)隱式調(diào)用shutdown()方法。

STOP:該狀態(tài)的線程池不接受新提交的任務(wù),也不處理在阻塞隊(duì)列中的任務(wù),還會(huì)中斷正在執(zhí)行的任務(wù)。(政府服務(wù)大廳不再進(jìn)行服務(wù)了,拿號(hào)、排隊(duì)、以及手頭工作都停止了。)

在線程池處于 RUNNING 或 SHUTDOWN 狀態(tài)時(shí),調(diào)用shutdownNow() 方法會(huì)使線程池進(jìn)入到該狀態(tài);

TIDYING:如果所有的任務(wù)都已終止,workerCount (有效線程數(shù))=0。

線程池進(jìn)入該狀態(tài)后會(huì)調(diào)用 terminated() 鉤子方法進(jìn)入TERMINATED 狀態(tài)。

TERMINATED:在terminated()鉤子方法執(zhí)行完后進(jìn)入該狀態(tài),默認(rèn)terminated()鉤子方法中什么也沒(méi)有做。

【參考文章】

【1】《JAVA并發(fā)編程藝術(shù)》

【2】tech.meituan.com/2020/04/02/…

總結(jié)

到此這篇關(guān)于Java線程池必知必會(huì)知識(shí)點(diǎn)的文章就介紹到這了,更多相關(guān)Java線程池必知必會(huì)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA的Random類的用法詳解

    JAVA的Random類的用法詳解

    Random類主要用來(lái)生成隨機(jī)數(shù),本文詳解介紹了Random類的用法,希望能幫到大家。
    2016-04-04
  • JMeter自定義日志與日志分析的實(shí)現(xiàn)

    JMeter自定義日志與日志分析的實(shí)現(xiàn)

    JMeter與Java程序一樣,會(huì)記錄事件日志,本文就介紹一下JMeter自定義日志與日志分析的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Java分頁(yè)查詢--分頁(yè)顯示(實(shí)例講解)

    Java分頁(yè)查詢--分頁(yè)顯示(實(shí)例講解)

    下面小編就為大家?guī)?lái)一篇Java分頁(yè)查詢--分頁(yè)顯示(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 關(guān)于SpringCloud的微服務(wù)結(jié)構(gòu)及微服務(wù)遠(yuǎn)程調(diào)用

    關(guān)于SpringCloud的微服務(wù)結(jié)構(gòu)及微服務(wù)遠(yuǎn)程調(diào)用

    Spring Cloud 是一套完整的微服務(wù)解決方案,基于 Spring Boot 框架,準(zhǔn)確的說(shuō),它不是一個(gè)框架,而是一個(gè)大的容器,它將市面上較好的微服務(wù)框架集成進(jìn)來(lái),從而簡(jiǎn)化了開發(fā)者的代碼量,需要的朋友可以參考下
    2023-05-05
  • Spring Security加密和匹配及原理解析

    Spring Security加密和匹配及原理解析

    我們開發(fā)時(shí)進(jìn)行密碼加密,可用的加密手段有很多,比如對(duì)稱加密、非對(duì)稱加密、信息摘要等,本篇文章給大家介紹Spring Security加密和匹配及原理解析,感興趣的朋友一起看看吧
    2023-10-10
  • IDEA 阿里JAVA規(guī)范插件的具體使用

    IDEA 阿里JAVA規(guī)范插件的具體使用

    這篇文章主要介紹了IDEA 阿里JAVA規(guī)范插件的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Java利用TreeUtils工具類實(shí)現(xiàn)列表轉(zhuǎn)樹

    Java利用TreeUtils工具類實(shí)現(xiàn)列表轉(zhuǎn)樹

    在開發(fā)過(guò)程中,總有列表轉(zhuǎn)樹的需求,幾乎是項(xiàng)目的標(biāo)配,有沒(méi)有一種通用且跨項(xiàng)目的解決方式呢?本文將基于Java8的Lambda?表達(dá)式和Stream等知識(shí),使用TreeUtils工具類實(shí)現(xiàn)一行代碼完成列表轉(zhuǎn)樹這一通用型需求,需要的可以參考一下
    2022-11-11
  • Spring Boot應(yīng)用監(jiān)控的實(shí)戰(zhàn)教程

    Spring Boot應(yīng)用監(jiān)控的實(shí)戰(zhàn)教程

    Spring Boot 提供運(yùn)行時(shí)的應(yīng)用監(jiān)控和管理功能,下面這篇文章主要給大家介紹了關(guān)于Spring Boot應(yīng)用監(jiān)控的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05
  • 一文搞懂Java設(shè)計(jì)模式之責(zé)任鏈模式

    一文搞懂Java設(shè)計(jì)模式之責(zé)任鏈模式

    這篇文章主要給大家介紹了關(guān)于Java設(shè)計(jì)模式之責(zé)任鏈模式的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Java操作透明圖片并保持背景透明的實(shí)現(xiàn)

    Java操作透明圖片并保持背景透明的實(shí)現(xiàn)

    這篇文章主要介紹了Java操作透明圖片并保持背景透明的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11

最新評(píng)論