JDK的線程池有三個(gè)重要的參數(shù)谒主,corePoolSize穗泵,maximumPoolSize和一個(gè)阻塞隊(duì)列workQueue吁峻,當(dāng)線程池中線程數(shù)量小于corePoolSize的時(shí)候直接開啟新的線程卖漫,運(yùn)行新加入的Runnable或者Callable宣旱,以后加入的Runnable或者Callable或加到阻塞隊(duì)列直到阻塞隊(duì)列滿了以后才起送新的Thread運(yùn)行新的Thread仅父,以下是代碼:
public void execute(Runnable command) {
? ? ? ? if (command == null)
? ? ? ? ? ? throw new NullPointerException();
?? ? int c = ctl.get();
? ? ? ? if (workerCountOf(c) < corePoolSize) {//如果當(dāng)前線程數(shù)小于corePoolSize,
? ? ? ? ? ? if (addWorker(command, true))//直接開啟新的Thread
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? c = ctl.get();
? ? ? ? }
? ? ? ? if (isRunning(c) && workQueue.offer(command)) {//添加進(jìn)隊(duì)列
? ? ? ? ? ? int recheck = ctl.get();
? ? ? ? ? ? if (! isRunning(recheck) && remove(command))
? ? ? ? ? ? ? ? reject(command);
? ? ? ? ? ? else if (workerCountOf(recheck) == 0)
? ? ? ? ? ? ? ? addWorker(null, false);
? ? ? ? }
? ? ? ? else if (!addWorker(command, false))//如果添加進(jìn)阻塞隊(duì)列失敗,則開啟新的Thread
? ? ? ? ? ? reject(command);
? ? }
Tomcat對此進(jìn)行了依靠重新實(shí)現(xiàn)阻塞隊(duì)列笙纤,實(shí)現(xiàn)了當(dāng)當(dāng)前線程數(shù)大于CorePoolSize但是小于MaxPoolSize的時(shí)候直接開啟新的線程Thread耗溜,而不是去加入阻塞隊(duì)列
public class TaskQueue extends LinkedBlockingQueue
繼承了JDK的LinkedBlockingQueue
重寫的offer方法
@Override
? ? public boolean offer(Runnable o) {
? ? ? //we can't do any checks
? ? ? ? if (parent==null) return super.offer(o);//如果對應(yīng)的線程池不存在為null調(diào)用父類的super.offer(o)
? ? ? ? //we are maxed out on threads, simply queue the object
? ? ? ? if (parent.getPoolSize() == parent.getMaximumPoolSize()) return super.offer(o);//如果線程池的線程數(shù)已經(jīng)等于所配置的最大線程數(shù)調(diào)用父類的super.offer(o)
? ? ? ? //we have idle threads, just add it to the queue
? ? ? ? if (parent.getSubmittedCount()<(parent.getPoolSize())) return super.offer(o);//如果已提交的任務(wù)小于當(dāng)前線程池的線程數(shù)表示有空閑的線程直接調(diào)用父類的super.offer(o)
? ? ? ? //if we have less threads than maximum force creation of a new thread
? ? ? ? if (parent.getPoolSize()
通過自定義阻塞隊(duì)列重寫offer方法實(shí)現(xiàn)對線程池實(shí)現(xiàn)方法的改變