日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java自定义线程_Java自定义线程池详解

發布時間:2023/12/10 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java自定义线程_Java自定义线程池详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

自定義線程池的核心:ThreadPoolExecutor

為了更好的控制多線程,JDK提供了一套線程框架Executor,幫助開發人員有效的進行線程控制,其中在java.util.concurrent包下,是JDK并發包的核心,比如我們熟知的Executors。Executors扮演著線程工廠的角色,我們通過它可以創建特定功能的線程池,而這些線程池背后的就是:ThreadPoolExecutor。那么下面我們來具體分析下它。

構造ThreadPoolExecutor

public?ThreadPoolExecutor(int?corePoolSize,

int?maximumPoolSize,

long?keepAliveTime,

TimeUnit?unit,

BlockingQueue?workQueue,

ThreadFactory?threadFactory,

RejectedExecutionHandler?handler)?{

if?(corePoolSize?

maximumPoolSize?<=?0?||

maximumPoolSize?

keepAliveTime?

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;

}

corePoolSize:核心線程數

maximumPoolSize:最大線程數

keepAliveTime + unit:線程回收時間

workQueue:任務較多時暫存到隊列

threadFactory:執行程序創建新線程時使用的工廠

handler:超出線程池容量以及隊列長度后拒絕任務的策略

有界隊列 or ×××隊列

我們知道對于BlockingQueue而言,有典型的有界隊列ArrayBlockingQueue以及LinkedBlockingQueue這種×××隊列,那么對于線程池而言,workQueue采用有界隊列、×××隊列會產生什么影響呢?如果采用×××隊列,那么會存在拒絕策略嗎?顯然不會,因為容量是無限的,比如沒有預定義容量的LinkedBlockingQueue。比如,在某個時段突發很多請求,那么采用×××隊列就保證了增長的可能性,而不是拒絕。如果采用有界隊列,相比×××隊列而言,有助于防止資源耗盡,在實際中我們經常在拒絕策略中記錄log,然后通過定時任務的方式進行處理。

接著上面的分析思路,想一想采用有界隊列、×××隊列中線程池的大小,這里涉及到一個問題,那就是任務增長時,是先增長至maximumPoolSize,還是先暫存到隊列中的問題?

corePoolSize and maximumPoolSize

一個是核心線程數,一個是最大線程數,怎么理解呢?在線程池初始化階段,是否已經初始化好corePoolSize個線程呢?大量任務來了后,線程池中的線程怎么變化?任務完成處理后,線程池又是如何回收的,回收到什么程度?

下面先來看一個線程池處理流程圖:

簡單一句話:提交任務,線程池中的線程數可以增長至corePoolSize,之后繼續提交任務將暫存至隊列中,如果隊列滿,則看是否能繼續增長線程數至maximumPoolSize,超出后將進行拒絕策略處理。顯然,如果采用×××隊列,那么maximumPoolSize將失效,線程池中的線程最多就是corePoolSize個線程工作。

從這里我們也可以看出,在需要判斷是否corePoolSize是否已經達到,需要鎖的介入,因此我們應盡量讓線程啟動后線程池的大小就處于>=corePoolSize個數,提前預熱。

keepAliveTime + unit

這里涉及到線程池回收線程。簡單來說,就是采用有界隊列,導致corePoolSize滿,隊列滿,不得已線程池的線程增長至maximumPoolSize,那么任務處理完畢后,線程池中多出corePoolSize的部分理應回收,那么等待多長時間,多長時間沒有任務后在進行回收的問題就是由上面的參數決定。

Executors創建線程池實例分析

固定線程池

特點:

×××隊列,導致keepAliveTime/unit/maximumPoolSize失效,不存在拒絕;

隨著任務的增長,線程數將固定在corePoolSize。

緩存線程池

特點:

一個比較特殊的隊列:SynchronousQueue,沒有容量可言,提交任務就意味著一直阻塞等待任務的線程立刻得到任務進行執行。說白了,就是不要暫存到隊列中,任務直接提交給線程進行執行。由于任務無法暫存,因此緩存線程池會根據任務的實際情況,進行線程池的增長,直至maximumPoolSize(Integer.MAX_VALUE)。

注意到keepAliveTime被設置成了60S,意思就是說如果任務來了很多,緩存線程池創建了不少線程來對付它們,任務處理的差不多了,那么等待60S后,還沒有任務需要處理,那么進行線程回收處理。

單線程池

特點:

×××隊列+核心、最大線程數都是1。

打個簡單比喻,任務來了,不管多少,那么有序的放著,工人只有一個,那就按照順序處理任務就是了。就是一個單線程順序處理任務的情況。

定時線程池

特點:

利用延時隊列DelayedQueue(×××隊列),完成線程池實現定時以及周期性執行任務的需要。

拒絕策略

JDK已經提供了幾種拒絕策略,如下所示:

我們需要自定義決絕策略時,很簡單,直接實現RejectedExecutionHandler的rejectedExecution方法即可。

總結

以上是生活随笔為你收集整理的java自定义线程_Java自定义线程池详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。