JDK的线程池有三个重要的参数,corePoolSize,maximumPoolSize和一个阻塞队列workQueue,当线程池中线程数量小于corePoolSize的时候直接开启新的线程,运行新加入的Runnable或者Callable,以后加入的Runnable或者Callable或加到阻塞队列直到阻塞队列满了以后才起送新的Thread运行新的Thread,以下是代码:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {//如果当前线程数小于corePoolSize,
if (addWorker(command, true))//直接开启新的Thread
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {//添加进队列
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))//如果添加进阻塞队列失败,则开启新的Thread
reject(command);
}
Tomcat对此进行了依靠重新实现阻塞队列,实现了当当前线程数大于CorePoolSize但是小于MaxPoolSize的时候直接开启新的线程Thread,而不是去加入阻塞队列
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);//如果对应的线程池不存在为null调用父类的super.offer(o)
//we are maxed out on threads, simply queue the object
if (parent.getPoolSize() == parent.getMaximumPoolSize()) return super.offer(o);//如果线程池的线程数已经等于所配置的最大线程数调用父类的super.offer(o)
//we have idle threads, just add it to the queue
if (parent.getSubmittedCount()<(parent.getPoolSize())) return super.offer(o);//如果已提交的任务小于当前线程池的线程数表示有空闲的线程直接调用父类的super.offer(o)
//if we have less threads than maximum force creation of a new thread
if (parent.getPoolSize()
通过自定义阻塞队列重写offer方法实现对线程池实现方法的改变
网友评论