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);