Tomcat中的线程池StandardThreadExecutor

时间:2023-03-08 21:30:59
Tomcat中的线程池StandardThreadExecutor

之所以今天讨论它,因为在motan的的NettyServer中利用它这个线程池可以作为业务线程池,它定制了一个自己的线程池。当然还是基于jdk中的ThreadExecutor中的构造方法和execute方法,然后在外边包装一层。

public ThreadPoolExecutor(int corePoolSize,

                          int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
  public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
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))
reject(command);
}

ThreadExecutor中的execute方法

从execute  方法的注释清晰得知,传统线程加入线程池执行过程分3步

小于等于Coresize: 创建线程之行

大于CoreSize  加入队列

队列满且小于maxSize  有空闲线程使用空闲线程执行,没有的话,创建线程执行

大于maxSize  拒绝策略执行


现在需要按照如下方式改造

 /**
* <pre>
*
* 代码和思路主要来自于:
*
* tomcat :
* org.apache.catalina.core.StandardThreadExecutor
*
* java.util.concurrent
* threadPoolExecutor execute执行策略: 优先offer到queue,queue满后再扩充线程到maxThread,如果已经到了maxThread就reject
* 比较适合于CPU密集型应用(比如runnable内部执行的操作都在JVM内部,memory copy, or compute等等)
*
* StandardThreadExecutor execute执行策略: 优先扩充线程到maxThread,再offer到queue,如果满了就reject
* 比较适合于业务处理需要远程资源的场景
*
* </pre>

具体的方式自己改造一个队列,在队列入队的方式下功夫。