為提高處理能力和併發度,web容器一般會把處理請求的任務放到執行緒池,而jdk的原生執行緒池先天適合cpu密集型任務,於是tomcat改造之。
其實threadpoolexecutor的引數主要有如下關鍵點:
限制執行緒個數
限制佇列長度
而tomcat對這倆資源都需要限制,否則高併發下cpu、記憶體都有被耗盡可能。
因此tomcat的執行緒池傳參:
// 定製的任務佇列
taskqueue = new taskqueue(maxqueuesize);
// 定製的執行緒工廠
taskthreadfactory tf = new task程式設計客棧threadfactory(nameprefix,
daemon,
getthreadpriority()
);// 定製執行緒池
executor = new threadpoolexecutor(getminsparethreads(),
getmaxthreads(),
maxidletime,
timeunit.milliseconds,
taskqueue,
tf);
www.cppcns.comtomcat對執行緒數也有限制,設定:
tomcat執行緒池還有自己的特色任務處理流程,通過重寫execute方法實現了自己的特色任務處理邏輯:
和 jdk 執行緒池的區別就在step3,tomcat**程總數達到最大數時,不是立即執行拒絕策略,而是再嘗試向任務佇列新增任務,新增失敗後再執行拒絕策略。
具體又是如何實現的呢?
public void execute(runnable command, long timeout, timeunit unit) catch (rejectedexecutionexception rx)
程式設計客棧 } }}
程式設計客棧}
tomcat執行緒池的execute方法第一行:
submittedcount.incrementandget();
任務執行失敗,拋異常時,將該計數器減一:
submittedcount.decrementandget();
tomcat執行緒池使用submittedcount變數維護已提交到執行緒池,但未執行完的任務數量。
為何要維護這樣乙個變數呢?
tomcat的任務佇列taskqueue擴充套件了jdk的linkedblockingqueue,tomcat給了它乙個capacity,傳給父類linkedblockingqueue的構造器。
public class taskqueue extends linkedblockingqueue
...}
capacity引數通過tomcat的maxqueuesize引數設定,但maxqueuesize預設值integer.max_value:當前執行緒數達到核心執行緒數後,再來任務的話執行緒池會把任務新增到任務佇列,並且總會成功,就永遠無機會建立新執行緒了。
為解決該問題,taskqueue重寫了linkedblockingqueue#offer,在合適時機返回false,表示任務新增失敗,這時執行緒池就會建立新執行緒。
什麼叫合適時機?
public www.cppcns.comclass taskqueue extends linkedblockingqueue {
...@override
// 執行緒池呼叫任務佇列的方法時,當前執行緒數 > core執行緒數
public boolean offer(runnable o) {
// 若執行緒數已達max,則不能建立新執行緒,只能放入任務佇列
if (parent.getpoolsize() == parent.getmaximumpoolsize())
return super.offer(o);
// 至此,表明 max執行緒數 > 當前執行緒數 > core執行緒數
// 說明可建立新執行緒:
// 1. 若已提交任務數 < 當前執行緒數
// 表明還有空閒執行緒,無需建立新執行緒
if (parent.getsubmittedcount()<=(parent.getpoolsize()))
return super.offer(o);
// 2. 若已提交任務數 > 當前執行緒數
// 執行緒不夠用了,返回false去建立新執行緒
if (parent.getpoolsize()
所以tomcat維護已提交任務數是為了在任務佇列長度無限時,讓執行緒池還能有機會建立新執行緒。
tomcat優化jdk原生的執行緒池
佇列進行定製為taskqueue public void execute runnable command,long timeout,timeunit unit catch rejectedexecutionexception rx catch interruptedexception x else...
Tomcat指定jdk 執行
取這個標題是為了更多的人能看到這個部落格,其實tomcat執行只要jre就可以了,所有我們只要設定jre 目錄就可以了。當然,你設定jdk的目錄也是沒有問題的。下面我們演示的是只配置jre目錄 在 tomcat的bin目錄下,找到setclasspath.bat開啟編輯。在 echo off下增加 ...
JDK 執行緒池
在jdk的4種執行緒池之前,先介紹一下執行緒池的幾個引數 固定執行緒池數量,核心執行緒數 最大執行緒數 任務佇列 linkedblockingqueue integer.max value 無界佇列 適用於同時處理固定任務數的場景.public static executorservice newf...