ThreadPoolExecutor 将根据 corePoolSize(参见 getCorePoolSize())和 maximumPoolSize(参见 getMaximumPoolSize())设置的边界自动调整池大小。当新任务在方法 execute(java.lang.Runnable) 中提交时,如果运行的线程少于 corePoolSize,则创建新线程来处理请求,即使其他辅助线程是空闲的。如果运行的线程多于 corePoolSize 而少于 maximumPoolSize,则仅当队列满时才创建新线程。
使用LinkedBlockingQueue作为示例队列:
private static void LinkedBlockingQueue(){
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
.setNameFormat("demo-pool-%d").build();
int queueCapacity = 3, corePoolSize=2, maximumPoolSize=3;
LinkedBlockingQueue linkedBlockingQueue = new LinkedBlockingQueue(queueCapacity);
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,10, TimeUnit.SECONDS,linkedBlockingQueue,namedThreadFactory);
for(int i=1;i<21;i++){
Thread thread = namedThreadFactory.newThread(new Task(i));
System.out.println("即将添加数据:"+i);
threadPoolExecutor.execute(thread);
System.out.println("i:"+i+", queueSize:"+linkedBlockingQueue.size()
+", poolSize:"+threadPoolExecutor.getPoolSize()
+", coreSize:"+threadPoolExecutor.getCorePoolSize()
+", maxSize:"+threadPoolExecutor.getMaximumPoolSize());
}
看打印的日志:
即将添加数据:1
i:1, queueSize:0, poolSize:1, coreSize:2, maxSize:3
即将添加数据:2
i:2, queueSize:0, poolSize:2, coreSize:2, maxSize:3
即将添加数据:3
i:3, queueSize:1, poolSize:2, coreSize:2, maxSize:3
即将添加数据:4
i:4, queueSize:2, poolSize:2, coreSize:2, maxSize:3
即将添加数据:5
i:5, queueSize:3, poolSize:2, coreSize:2, maxSize:3
即将添加数据:6
i:6, queueSize:3, poolSize:3, coreSize:2, maxSize:3
即将添加数据:7
Exception in thread "main" java.util.concurrent.RejectedExecutionException
当添加第一个任务的时候,由于线程池空着,直接创建核心线程来处理请求;
当已经添加完两个请求,添加第三个请求的时候,核心线程数已满,则往队列里面添加,此时queueSize=1;
添加3、4、5任务,都被添加到了队列里面,此时queueSize=3;
添加6任务的时候,核心线程已满,队列已满,运行的线程数小于maximumPoolSize,那么线程池再处理一个任务,此时poolSize=3,线程池的任务满了;
添加7任务的时候,由于线程池里面的任务还没有执行完,而队列也是满的,线程池处理不了这么多任务了,抛出异常java.util.concurrent.RejectedExecutionException。