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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

java corepoolsize_理解ThreadPoolExecutor线程池的corePoolSize、maximumPoolSize和poolSize

發布時間:2023/12/2 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java corepoolsize_理解ThreadPoolExecutor线程池的corePoolSize、maximumPoolSize和poolSize 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們知道,受限于硬件、內存和性能,我們不可能無限制的創建任意數量的線程,因為每一臺機器允許的最大線程是一個有界值。也就是說ThreadPoolExecutor管理的線程數量是有界的。線程池就是用這些有限個數的線程,去執行提交的任務。然而對于多用戶、高并發的應用來說,提交的任務數量非常巨大,一定會比允許的最大線程數多很多。為了解決這個問題,必須要引入排隊機制,或者是在內存中,或者是在硬盤等容量很大的存儲介質中。J.U.C提供的ThreadPoolExecutor只支持任務在內存中排隊,通過BlockingQueue暫存還沒有來得及執行的任務。

任務的管理是一件比較容易的事,復雜的是線程的管理,這會涉及線程數量、等待/喚醒、同步/鎖、線程創建和死亡等問題。ThreadPoolExecutor與線程相關的幾個成員變量是:keepAliveTime、allowCoreThreadTimeOut、poolSize、corePoolSize、maximumPoolSize,它們共同負責線程的創建和銷毀。

corePoolSize:

線程池的基本大小,即在沒有任務需要執行的時候線程池的大小,并且只有在工作隊列滿了的情況下才會創建超出這個數量的線程。這里需要注意的是:在剛剛創建ThreadPoolExecutor的時候,線程并不會立即啟動,而是要等到有任務提交時才會啟動,除非調用了prestartCoreThread/prestartAllCoreThreads事先啟動核心線程。再考慮到keepAliveTime和allowCoreThreadTimeOut超時參數的影響,所以沒有任務需要執行的時候,線程池的大小不一定是corePoolSize。

maximumPoolSize:

線程池中允許的最大線程數,線程池中的當前線程數目不會超過該值。如果隊列中任務已滿,并且當前線程個數小于maximumPoolSize,那么會創建新的線程來執行任務。這里值得一提的是largestPoolSize,該變量記錄了線程池在整個生命周期中曾經出現的最大線程個數。為什么說是曾經呢?因為線程池創建之后,可以調用setMaximumPoolSize()改變運行的最大線程的數目。

poolSize:

線程池中當前線程的數量,當該值為0的時候,意味著沒有任何線程,線程池會終止;同一時刻,poolSize不會超過maximumPoolSize。

現在我們通過ThreadPoolExecutor.execute()方法,看一下這3個屬性的關系,以及線程池如何處理新提交的任務。以下源碼基于JDK1.6.0_37版本。

private booleanaddIfUnderCorePoolSize(Runnable firstTask) {

Thread t= null;final ReentrantLock mainLock = this.mainLock;

mainLock.lock();try{if (poolSize < corePoolSize && runState ==RUNNING)

t=addThread(firstTask);

}finally{

mainLock.unlock();

}if (t == null)return false;

t.start();return true;

}private booleanaddIfUnderMaximumPoolSize(Runnable firstTask) {

Thread t= null;final ReentrantLock mainLock = this.mainLock;

mainLock.lock();try{if (poolSize < maximumPoolSize && runState ==RUNNING)

t=addThread(firstTask);

}finally{

mainLock.unlock();

}if (t == null)return false;

t.start();return true;

}

新提交一個任務時的處理流程很明顯:

1、如果當前線程池的線程數還沒有達到基本大小(poolSize < corePoolSize),無論是否有空閑的線程新增一個線程處理新提交的任務;

2、如果當前線程池的線程數大于或等于基本大小(poolSize >= corePoolSize)?且任務隊列未滿時,就將新提交的任務提交到阻塞隊列排隊,等候處理workQueue.offer(command);

3、如果當前線程池的線程數大于或等于基本大小(poolSize >= corePoolSize)?且任務隊列滿時;

3.1、當前poolSize

3.2、當前poolSize=maximumPoolSize,那么意味著線程池的處理能力已經達到了極限,此時需要拒絕新增加的任務。至于如何拒絕處理新增的任務,取決于線程池的飽和策略RejectedExecutionHandler。

Queuing

Any BlockingQueue may be used to transfer and hold submitted tasks. The use of this queue interacts with pool sizing:

If fewer than corePoolSize threads are running, the Executor always prefers adding a new thread rather than queuing.

If corePoolSize or more threads are running, the Executor always prefers queuing a request rather than adding a new thread.

If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.

1、corePoolSize:核心線程數*核心線程會一直存活,及時沒有任務需要執行*當線程數小于核心線程數時,即使有線程空閑,線程池也會優先創建新線程處理*設置allowCoreThreadTimeout=true(默認false)時,核心線程會超時關閉2、queueCapacity:任務隊列容量(阻塞隊列)*當核心線程數達到最大時,新任務會放在隊列中排隊等待執行3、maxPoolSize:最大線程數*當線程數>=corePoolSize,且任務隊列已滿時。線程池會創建新線程來處理任務*當線程數=maxPoolSize,且任務隊列已滿時,線程池會拒絕處理任務而拋出異常4、keepAliveTime:線程空閑時間*當線程空閑時間達到keepAliveTime時,線程會退出,直到線程數量=corePoolSize

*如果allowCoreThreadTimeout=true,則會直到線程數量=05、allowCoreThreadTimeout:允許核心線程超時6、rejectedExecutionHandler:任務拒絕處理器*兩種情況會拒絕處理任務:-當線程數已經達到maxPoolSize,切隊列已滿,會拒絕新任務-當線程池被調用shutdown()后,會等待線程池里的任務執行完畢,再shutdown。如果在調用shutdown()和線程池真正shutdown之間提交任務,會拒絕新任務*線程池會調用rejectedExecutionHandler來處理這個任務。如果沒有設置默認是AbortPolicy,會拋出異常*ThreadPoolExecutor類有幾個內部實現類來處理這類情況:-AbortPolicy丟棄任務,拋運行時異常-CallerRunsPolicy執行任務-DiscardPolicy忽視,什么都不會發生-DiscardOldestPolicy從隊列中踢出最先進入隊列(最后一個執行)的任務*實現RejectedExecutionHandler接口,可自定義處理器

接下來我們看下allowCoreThreadTimeOut和keepAliveTime屬性的含義。在壓力很大的情況下,線程池中的所有線程都在處理新提交的任務或者是在排隊的任務,這個時候線程池處在忙碌狀態。如果壓力很小,那么可能很多線程池都處在空閑狀態,這個時候為了節省系統資源,回收這些沒有用的空閑線程,就必須提供一些超時機制,這也是線程池大小調節策略的一部分。通過corePoolSize和maximumPoolSize,控制如何新增線程;通過allowCoreThreadTimeOut和keepAliveTime,控制如何銷毀線程。

allowCoreThreadTimeOut:

該屬性用來控制是否允許核心線程超時退出。默認值為:false。If false,core threads stay alive even when idle.If true, core threads use keepAliveTime to time out waiting for work。如果線程池的大小已經達到了corePoolSize,不管有沒有任務需要執行,線程池都會保證這些核心線程處于存活狀態。可以知道:該屬性只是用來控制核心線程的。

keepAliveTime:

如果一個線程處在空閑狀態的時間超過了該屬性值,就會因為超時而退出。舉個例子,如果線程池的核心大小corePoolSize=5,而當前大小poolSize =8,那么超出核心大小的線程,會按照keepAliveTime的值判斷是否會超時退出。如果線程池的核心大小corePoolSize=5,而當前大小poolSize =5,那么線程池中所有線程都是核心線程,這個時候線程是否會退出,取決于allowCoreThreadTimeOut。

Runnable getTask() {for(;;) {try{int state =runState;if (state >SHUTDOWN)return null;

Runnable r;if (state == SHUTDOWN) //Help drain queue

r =workQueue.poll();else if (poolSize > corePoolSize ||allowCoreThreadTimeOut)

r=workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS);elser=workQueue.take();if (r != null)returnr;if(workerCanExit()) {if (runState >= SHUTDOWN) //Wake up others

interruptIdleWorkers();return null;

}//Else retry

} catch(InterruptedException ie) {//On interruption, re-check runState

}

}

}

(poolSize > corePoolSize || allowCoreThreadTimeOut)這個條件,就是用來判斷是否允許當前線程退出。workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS);就是借助阻塞隊列,讓空閑線程等待keepAliveTime時間之后,恢復執行。這樣空閑線程會由于超時而退出。

總結

以上是生活随笔為你收集整理的java corepoolsize_理解ThreadPoolExecutor线程池的corePoolSize、maximumPoolSize和poolSize的全部內容,希望文章能夠幫你解決所遇到的問題。

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