ThreadPoolExecutor的常见的队列到底能够存放多少任务
ThreadPoolExecutor 的常见的任务队列有LinkedBlockingDeque和SynchronousQueue2种,其实任务队列也是有长度的,上一节都是默认长度。试想一下这种情况,假如线程池里的线程数+对列里的任务数都<线程数的情况下,该怎么办呢,接着举例说明
定义公共任务
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + "在运行" + System.currentTimeMillis());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
};
使用LinkedBlockingDeque 队列
1、LinkedBlockingDeque 队列:maximumPoolSize>=线程数>corePoolSize,且 线程数>corePoolSize+队列长度,此时就会启动(线程数-corePoolSize-队列长度)个非核心线程去执行任务。
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4, 9, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>(2));
for (int i = 0; i < 8; i++) {
threadPoolExecutor.execute(runnable);
try {
Thread.sleep(500);
System.out.println("A===" + threadPoolExecutor.getCorePoolSize());
System.out.println("A===" + threadPoolExecutor.getPoolSize());
System.out.println("A===" + threadPoolExecutor.getQueue().size());
Thread.sleep(3000);
System.out.println("B===" + threadPoolExecutor.getCorePoolSize());
System.out.println("B===" + threadPoolExecutor.getPoolSize());
System.out.println("B===" + threadPoolExecutor.getQueue().size());
} catch (InterruptedException e) {
e.printStackTrace();
}
执行结果
一共8个任务,核心线程4个,队列2个,还差2个去启动了非核心线程,由于keepAliveTime设置0L,所以这2个非核心线程执行完就over了。
2、LinkedBlockingDeque队列:maximumPoolSize+队列长度>=线程数>maximumPoolSize,此时就会启动(线程数-corePoolSize-队列长度)个非核心线程去执行任务。
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4, 9, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>(2));
for (int i = 0; i < 11; i++) {
threadPoolExecutor.execute(runnable);
try {
Thread.sleep(500);
System.out.println("A===" + threadPoolExecutor.getCorePoolSize());
System.out.println("A===" + threadPoolExecutor.getPoolSize());
System.out.println("A===" + threadPoolExecutor.getQueue().size());
Thread.sleep(3000);
System.out.println("B===" + threadPoolExecutor.getCorePoolSize());
System.out.println("B===" + threadPoolExecutor.getPoolSize());
System.out.println("B===" + threadPoolExecutor.getQueue().size());
} catch (InterruptedException e) {
e.printStackTrace();
}
执行结果,同上
3、LinkedBlockingDeque队列:当线程数>maximumPoolSize+队列长度,就会拒绝掉多余的任务,此时线程池火力全开,启动了maximumPoolSize个线程(包含核心线程),同时队列里也满了
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4, 9, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>(2));
for (int i = 0; i < 12; i++) {
threadPoolExecutor.execute(runnable);
try {
Thread.sleep(500);
System.out.println("A===" + threadPoolExecutor.getCorePoolSize());
System.out.println("A===" + threadPoolExecutor.getPoolSize());
System.out.println("A===" + threadPoolExecutor.getQueue().size());
Thread.sleep(3000);
System.out.println("B===" + threadPoolExecutor.getCorePoolSize());
System.out.println("B===" + threadPoolExecutor.getPoolSize());
System.out.println("B===" + threadPoolExecutor.getQueue().size());
} catch (InterruptedException e) {
e.printStackTrace();
}
执行结果
4、LinkedBlockingDeque队列:如果队列不指定对列长度的话,那么默认使用的就是Integer. MAX_VALUE,一切就和上一节的例子一样,只启动核心线程处理,多余的都放到对列里就行了
使用 SynchronousQueue 队列
1、当线程数<=maximumPoolSize时候,和上一节一样,队列为空,启动 (线程数-corePoolSize) 个非核心线程来执行任务
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4, 9, 0L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
for (int i = 0; i < 8; i++) {
threadPoolExecutor.execute(runnable);
try {
Thread.sleep(500);
System.out.println("A===" + threadPoolExecutor.getCorePoolSize());
System.out.println("A===" + threadPoolExecutor.getPoolSize());
System.out.println("A===" + threadPoolExecutor.getQueue().size());
Thread.sleep(3000);
System.out.println("B===" + threadPoolExecutor.getCorePoolSize());
System.out.println("B===" + threadPoolExecutor.getPoolSize());
System.out.println("B===" + threadPoolExecutor.getQueue().size());
} catch (InterruptedException e) {
e.printStackTrace();
}
执行结果
2、当线程数>maximumPoolSize时候,直接拒绝掉多余的任务。
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4, 9, 0L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
for (int i = 0; i < 10; i++) {
threadPoolExecutor.execute(runnable);
try {
Thread.sleep(500);
System.out.println("A===" + threadPoolExecutor.getCorePoolSize());
System.out.println("A===" + threadPoolExecutor.getPoolSize());
System.out.println("A===" + threadPoolExecutor.getQueue().size());
Thread.sleep(3000);