在的线程数目是:5, 队列中正在等待执行的任务数量为:2
线程池中现在的线程数目是:5, 队列中正在等待执行的任务数量为:3
线程池中现在的线程数目是:5, 队列中正在等待执行的任务数量为:4
线程池中现在的线程数目是:5, 队列中正在等待执行的任务数量为:5
线程池中现在的线程数目是:6, 队列中正在等待执行的任务数量为:5
线程池中现在的线程数目是:7, 队列中正在等待执行的任务数量为:5
线程池中现在的线程数目是:8, 队列中正在等待执行的任务数量为:5
线程池中现在的线程数目是:9, 队列中正在等待执行的任务数量为:5
线程池中现在的线程数目是:10, 队列中正在等待执行的任务数量为:5
可以看到当线程数增加到core数量的时候,队列中已经有任务了。
进一步思考
在使用ThreadPoolExecutor的时候,如果发生了RejectedExecutionException,该如何处理?本文中的代码是采用了重新将任务尝试插入到队列中,如果还是失败则直接将reject异常抛出去。
@Override
public void execute(Runnable command) {
submittedTaskCount.incrementAndGet();
try {
super.execute(command);
} catch (RejectedExecutionException rx) {
//当发生RejectedExecutionException,尝试再次将task丢到队列里面,如果还是发生RejectedExecutionException,则直接抛出异常。
BlockingQueue<Runnable> taskQueue = super.getQueue();
if (taskQueue instanceof TaskQueue) {
final TaskQueue queue = (TaskQueue)taskQueue;
if (!queue.forceTaskIntoQueue(command)) {
submittedTaskCount.decrementAndGet();
throw new RejectedExecutionException("队列已满");
}
} else {
submittedTaskCount.decrementAndGet();
throw rx;
}
}
}
TaskQueue类提供了forceTaskIntoQueue方法,将任务插入到队列中。
还有另一种解决方案,就是使用另外一个线程池来执行任务,当第一个线程池抛出Reject异常时,catch住它,并使用第二个线程池处理任务。