关于该类的文档 https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
描述中有以下内容
Core and maximum pool sizes
............. When a new task is submitted in method execute(java.lang.Runnable), and fewer than corePoolSize threads are running, a new thread is created to handle the request, even if other worker threads are idle. If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full.
当方法execute(java.lang.Runnable)中提交新任务并且运行的线程少于corePoolSize时,即使其他工作线程处于空闲状态,也会创建一个新线程来处理该请求。如果运行的线程数于介corePoolSizemaxi与mumPoolSize之间,则只有在队列已满时才会创建新线程。
Queuing
Any BlockingQueue may be used to transfer and hold submitted tasks. The use of this queue interacts with pool sizing:
- If fewer than corePoolSize threads are running, the Executor always prefers adding a new thread rather than queuing.
- If corePoolSize or more threads are running, the Executor always prefers queuing a request rather than adding a new thread.
- If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.
加粗部分意思: 如果线程池里的线程数大于corePoolSize,Executor会将新来的请求放进队列而不是增加一个新线程。
下面编写代码来证明:
public class ThreadPoolTest {
public static void main(String[] args) {
try {
createThreadDemo();
} catch (RejectedExecutionException e) {
e.printStackTrace();
System.exit(-1);
}
}
private static void createThreadDemo() throws RejectedExecutionException {
// 等待队列
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(6);
// 创建线程池, 核心线程数为5, 最大线程数为10
ThreadPoolExecutor pool = new ThreadPoolExecutor(5, 10, 600, TimeUnit.SECONDS, workQueue);
for (int i = 1; i < Integer.MAX_VALUE; i++) {
pool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(300000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
System.out.println("创建第" + i + "个线程后, 线程池情况:" + pool.toString());
}
}
}
输出:
pool-1-thread-1
创建第1个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
pool-1-thread-2
创建第2个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0]
pool-1-thread-3
创建第3个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 0]
pool-1-thread-4
创建第4个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 4, active threads = 4, queued tasks = 0, completed tasks = 0]
pool-1-thread-5
创建第5个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 5, active threads = 5, queued tasks = 0, completed tasks = 0]
创建第6个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 5, active threads = 5, queued tasks = 1, completed tasks = 0]
创建第7个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 5, active threads = 5, queued tasks = 2, completed tasks = 0]
创建第8个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 5, active threads = 5, queued tasks = 3, completed tasks = 0]
创建第9个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 5, active threads = 5, queued tasks = 4, completed tasks = 0]
创建第10个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 5, active threads = 5, queued tasks = 5, completed tasks = 0]
创建第11个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 5, active threads = 5, queued tasks = 6, completed tasks = 0]
pool-1-thread-6
创建第12个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 6, active threads = 6, queued tasks = 6, completed tasks = 0]
pool-1-thread-7
创建第13个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 7, active threads = 7, queued tasks = 6, completed tasks = 0]
pool-1-thread-8
创建第14个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 8, active threads = 8, queued tasks = 6, completed tasks = 0]
pool-1-thread-9
创建第15个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 9, active threads = 9, queued tasks = 6, completed tasks = 0]
pool-1-thread-10
创建第16个线程后, 线程池情况:java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 10, active threads = 10, queued tasks = 6, completed tasks = 0]
Disconnected from the target VM, address: '127.0.0.1:52079', transport: 'socket'
java.util.concurrent.RejectedExecutionException: Task utils.ThreadPoolTest$1@563da1dc rejected from java.util.concurrent.ThreadPoolExecutor@78457235[Running, pool size = 10, active threads = 10, queued tasks = 6, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)
at utils.ThreadPoolTest.createThreadDemo(ThreadPoolTest.java:32)
at utils.ThreadPoolTest.main(ThreadPoolTest.java:15)
我们创建了一个corePoolSize为5、maximumPoolSize为10的线程池。 由结果得知, 当线程池内活跃的线程数大于5时,再来新的创建请求会直接进入队列(队列数往上增),直接到达队列的界限(这里是6)后, 再来新的请求时pool size会一直增大直到达到maximumPoolSize为止。
结论: 线程池内活跃的线程数大于corePoolSize时, 新来的任务会先进队列, 如果队列满时会继续新建线程直到池内线程数达到maximumPoolSize为止。 这时如果再请求新的任务, 会执行设定的策略, 默认是直接拒绝创建。