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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java util下的并发包_jdk并发包下:使用java.util.concurrent.Executor线程池

發(fā)布時間:2025/3/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java util下的并发包_jdk并发包下:使用java.util.concurrent.Executor线程池 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

多線程,線程池Executor的接口類圖:

其他都不重要,就ExecutorService是主要的:

基本上分為單純線程池和定時任務線程池:

說白了除了ForkJoinPool所有都繼承于ThreadPoolExecutor或者是對ThreadPoolExecutor的包裝類:

//構(gòu)造函數(shù)

public ThreadPoolExecutor(

int corePoolSize,//從0增加,直到維持不變的線程數(shù)

int maximumPoolSize,//最大創(chuàng)建的線程數(shù),比corePoolSize多出來的是多余線程數(shù),如果空閑會被釋放

long keepAliveTime,//空閑多久釋放

TimeUnit unit,//keepAliveTime的單位

BlockingQueue workQueue,//任務隊列對象

ThreadFactory threadFactory,//線程生產(chǎn)工廠

RejectedExecutionHandler handler//壓力大時如何處理拒絕任務

) {

}

上面構(gòu)造方法的各個參數(shù)的默認值:

corePoolSize:一般是1或者cpu核心數(shù)或者其他定量

maximumPoolSize:一般是0或者無限大

keepAliveTime:一般是0或者60s

unit:一般是TimeUnit.SECONDS

workQueue:一般是AbstractQueue 的子類

threadFactory:一般是DefaultThreadFactory implements ThreadFactory實例

Executors提供的類實例化方法:

int corePoolSize = 4;

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(corePoolSize);

ExecutorService executorService1 = Executors.newSingleThreadExecutor();

ExecutorService executorService2 = Executors.newFixedThreadPool(corePoolSize);

ExecutorService executorService4 = Executors.newCachedThreadPool();

ExecutorService executorService3 = Executors.newWorkStealingPool(corePoolSize);

它們主要區(qū)別就是實例化的參數(shù)不同,比如固定的線程數(shù)是多少,并發(fā)高峰時的線程數(shù)能達到多少,空閑線程的存活時間不同,使用的保存任務的隊列類不同,繁忙時多余任務的拒絕策略,等等。

需要根據(jù)實際并發(fā)需求和特點來選擇不同的實例,或者自己實例化ThreadPoolExecutor直接使用。

創(chuàng)建好線程池后的調(diào)用就是submit(異步返回結(jié)果)和execute(不返回結(jié)果),其他方法 也簡單不說了。

說下最關(guān)心的ThreadPoolExecutor的參數(shù)對性能的影響:

過程如下:

當線程池初始化完成之后,而且當前線程數(shù)量小于corePoolSize,新來的任務直接通過創(chuàng)建線程來直接運行,并且線程運行后不會銷毀。

當線程池中正在運行的線程達到 corePoolSize 個時,不會繼續(xù)創(chuàng)建線程,任務會放到 taskQueue 中排隊等候;

當 taskQueue(阻塞隊列)的容量達到上限(即隊列中不能再加入任務線程了),而且設置的maximumPoolSize大于corePoolSize時,則新增額外線程來處理任務;

當 taskQueue 的容量達到上限,且 當前線程數(shù)poolSize 達到maximumPoolSize,那么線程池已經(jīng)達到極限,會根據(jù)飽和策略RejectedExecutionHandler處理新的任務。

測試驗證:

我設置核心線程數(shù)為4個,最大線程數(shù)為10個,隊列為10個滿容量,拒絕策略為拋異常:

int corePoolSize = 4;

int maximumPoolSize = 10;

long keepAliveTime = 10L;

TimeUnit unit = TimeUnit.SECONDS;

BlockingQueue workQueue = new LinkedBlockingQueue<>(10);

ThreadFactory threadFactory = Executors.defaultThreadFactory();

RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize,

maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);

,getActiveCount=0 ,getPoolSize=0 ,getTaskCount=0 ,getLargestPoolSize=0 ,getQueueSize=0

,getActiveCount=1 ,getPoolSize=1 ,getTaskCount=1 ,getLargestPoolSize=1 ,getQueueSize=0

,getActiveCount=2 ,getPoolSize=2 ,getTaskCount=2 ,getLargestPoolSize=2 ,getQueueSize=0

,getActiveCount=3 ,getPoolSize=3 ,getTaskCount=3 ,getLargestPoolSize=3 ,getQueueSize=0

,getActiveCount=4 ,getPoolSize=4 ,getTaskCount=4 ,getLargestPoolSize=4 ,getQueueSize=0

,getActiveCount=4 ,getPoolSize=4 ,getTaskCount=5 ,getLargestPoolSize=4 ,getQueueSize=1

,getActiveCount=4 ,getPoolSize=4 ,getTaskCount=6 ,getLargestPoolSize=4 ,getQueueSize=2

,getActiveCount=4 ,getPoolSize=4 ,getTaskCount=7 ,getLargestPoolSize=4 ,getQueueSize=3

,getActiveCount=4 ,getPoolSize=4 ,getTaskCount=8 ,getLargestPoolSize=4 ,getQueueSize=4

,getActiveCount=4 ,getPoolSize=4 ,getTaskCount=9 ,getLargestPoolSize=4 ,getQueueSize=5

,getActiveCount=4 ,getPoolSize=4 ,getTaskCount=10 ,getLargestPoolSize=4 ,getQueueSize=6

,getActiveCount=4 ,getPoolSize=4 ,getTaskCount=11 ,getLargestPoolSize=4 ,getQueueSize=7

,getActiveCount=4 ,getPoolSize=4 ,getTaskCount=12 ,getLargestPoolSize=4 ,getQueueSize=8

,getActiveCount=4 ,getPoolSize=4 ,getTaskCount=13 ,getLargestPoolSize=4 ,getQueueSize=9

,getActiveCount=4 ,getPoolSize=4 ,getTaskCount=14 ,getLargestPoolSize=4 ,getQueueSize=10

,getActiveCount=5 ,getPoolSize=5 ,getTaskCount=15 ,getLargestPoolSize=5 ,getQueueSize=10

,getActiveCount=6 ,getPoolSize=6 ,getTaskCount=16 ,getLargestPoolSize=6 ,getQueueSize=10

,getActiveCount=7 ,getPoolSize=7 ,getTaskCount=17 ,getLargestPoolSize=7 ,getQueueSize=10

,getActiveCount=8 ,getPoolSize=8 ,getTaskCount=18 ,getLargestPoolSize=8 ,getQueueSize=10

,getActiveCount=9 ,getPoolSize=9 ,getTaskCount=19 ,getLargestPoolSize=9 ,getQueueSize=10

,getActiveCount=10 ,getPoolSize=10 ,getTaskCount=20 ,getLargestPoolSize=10 ,getQueueSize=10

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.exemple.Test6$task@63947c6b rejected from java.util.concurrent.ThreadPoolExecutor@2b193f2d[Running, pool size = 10, active threads = 10, queued tasks = 10, completed tasks = 0]

at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)

at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)

at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)

at com.exemple.Test6.main(Test6.java:30)

從上面輸出可以解析,

前4個任務,線程數(shù)一直增長從1到4,說明小于corePoolSize時一直創(chuàng)建線程

5到14個任務,線程數(shù)不變,隊列添加從1到10,說明大于corePoolSize時加入隊列等待

14到20個任務,隊列不變,線程數(shù)又從4增長到10,說明隊列滿時又創(chuàng)建線程直到達到最大線程數(shù)

第21個任務,拋出異常,因為最大10線程+最大隊列10容量<21,說明線程和隊列都達到最大值后,根據(jù)拒絕策略處理。

ThreadPoolExecutor線程池自身是線程安全的,但是對于執(zhí)行的任務并不保證線程安全,也沒有任何線程同步操作。需要用戶自己處理線程安全。

以后看性能如何再改下面的猜測:

個人就基于并發(fā)峰值、任務平均處理時間等等,猜測創(chuàng)建線程池各個參數(shù)的合理區(qū)間:

平均并發(fā)數(shù)

高峰并發(fā)數(shù)

任務執(zhí)行時間

合理參數(shù)配置:

說明

固定線程數(shù)=低合理值(CPU核心數(shù))

最大線程數(shù)=2倍CPU核心

空閑線程等待時間=60s

隊列容量=較大合理值

拒絕策略=隊列不會滿用不到

并發(fā)不高,不需要運行太多線程,

任務易處理,多出來全部放隊列即可

很長

固定線程數(shù)=低合理值(CPU核心數(shù))

最大線程數(shù)=較大合理值

空閑線程等待時間=60s

隊列容量=中等合理值

拒絕策略=實際需要

并發(fā)不高,不需要運行太多線程,

任務時間長,盡可能利用線程數(shù)

極高

固定線程數(shù)=低合理值

最大線程數(shù)=較高合理值

空閑線程等待時間=60s

隊列容量=防止內(nèi)存溢出較大值

拒絕策略=還不滿足,考慮買設備

平時并發(fā)不高,不需要運行太多線程,

任務易處理,并發(fā)高峰放隊列和新線程

很高

極高

固定線程數(shù)=中等合理值

最大線程數(shù)=較高合理值

空閑線程等待時間=60s

隊列容量=防止內(nèi)存溢出最大值

拒絕策略=重要任務不拋棄,最大化利用內(nèi)存和cpu資源

平時并發(fā)高,需要運行較多線程,

任務易處理,提升隊列容量

很高

極高

很長

固定線程數(shù)=中等合理值

最大線程數(shù)=較高合理值

空閑線程等待時間=60s

隊列容量=防止內(nèi)存溢出最大值

拒絕策略=重要任務不拋棄,最大化利用內(nèi)存和cpu資源

長時間任務,應該考慮另外使用任務調(diào)度容器來執(zhí)行。

參數(shù)設置依據(jù):

平常并發(fā)操作一般的話,線程數(shù)不是越高越好,相對于物理真實的線程數(shù)和線程時間片時間長度,此參數(shù)設置應該合理區(qū)間,不然實質(zhì)上會經(jīng)常切換線程調(diào)度,消耗切換時間和資源。

為了提高線程池處理能力,如果設置隊列容量過大,當真的有大批任務過來,可能導致內(nèi)存溢出。而且隊列過大,就不再觸發(fā)最大線程數(shù)這個設置,一直都是固定線程處理任務。

Executors提供的四種創(chuàng)建線程池的參數(shù)配置,都是特別對應不同場景的較好設置值,值得參考。

總結(jié)

以上是生活随笔為你收集整理的java util下的并发包_jdk并发包下:使用java.util.concurrent.Executor线程池的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。