线程池的三种缓存队列

最近在看java的线程池,对于里面的三种缓存队列里面进行对比学习了下,感觉自己测试下来的结果和网上有些知识点不同相同,所以还希望有人能帮我解惑下。

概述

队列 简单解释
SynchrousQueue 不会保存提交任务,超出直接corePoolSize个任务,直接创建新的线程来执行任务,直到(corePoolSize+新建线程)> maximumPoolSize。不是核心线程就是新建线程。
LinkedBlockingQueue 基于链表的先进先出,无界队列。超出直接corePoolSize个任务,则加入到该队列中,直到资源耗尽,所以maximumPoolSize不起作用
ArrayBlockingQueue 基于数组的先进先出,创建时必须指定大小,超出直接corePoolSize个任务,则加入到该队列中,只能加该queue设置的大小,其余的任务则创建线程,直到(corePoolSize+新建线程)> maximumPoolSize

SynchrousQueue

创建一个corePoolSize为2,maximumPoolSize为3的线程池。执行6个任务。根据我的理解,SynchrousQueue是个一个无缓存的队列(理论依据为SynchrousQueue源码可以看到:isEmpty()始终为true;size()始终返回0)

根据参数设置应该只可以执行3个任务:

2个核心线程执行2个任务;
第3个任务的时候,创建线程来执行任务3;
当第4个任务来的时候,此时已经超过了maximumPoolSize,所以拒绝任务。(但是网上有些说法是这里是可以在缓存一个任务到队列中,我不太理解这种说法,还希望有人能解答下。)

创建线程池代码如下:


    /**
     * SynchronousQueue
     */
    private static void syncQueue() {
        System.out.println("\n\n =======SynchronousQueue====== \n\n");
        Executor executors = new ThreadPoolExecutor(
                2, 3, 30, TimeUnit.SECONDS,
                new SynchronousQueue(),
                new RejectHandler());
        execute(executors);
    }

执行结果如下:(跟我的预想是一样的)

1 is running... 
4 is rejected ^^ //4被拒
2 is running... 
3 is running... 
5 is rejected ^^  //5被拒
6 is rejected ^^  //6被拒
3 is end !!! 
1 is end !!! 
2 is end !!! 

 ArrayBlockingQueue

创建一个corePoolSize为2,maximumPoolSize为3的线程池。其中ArrayBlockingQueue设置缓存2个任务。执行6个任务。ArrayBlockingQueue为有界队列:

任务1和2在核心线程中执行;
任务3和4进来的时候,是放到ArrayBlockingQueue缓存队列中的,并且只能放2个(ArrayBlockingQueue设置的大小为2);
任务5和6进来的时候,任务5新建线程来执行任务,已经达到最大线程数3,所以任务6拒绝;
当有线程执行完的时候,再将任务3和4从队列中取出执行

创建线程池代码如下:

 

  /**
     * ArrayBlockingQueue
     */
    private static void arrayQueue() {
        System.out.println("\n\n =======ArrayBlockingQueue====== \n\n");
        Executor executors = new ThreadPoolExecutor(
                2, 3, 30, TimeUnit.SECONDS,
                new ArrayBlockingQueue(2),
                new RejectHandler());
        execute(executors);
    }

 

执行结果如下

1 is running... 
2 is running... 
6 is rejected ^^ //6被拒
5 is running...  //5新建线程执行
1 is end !!! 
2 is end !!! 
3 is running... //1和2执行完之后3和4才执行
4 is running... 
5 is end !!! 

LinkedBlockingQueue

创建一个corePoolSize为2,maximumPoolSize为3的线程池。无界队列。同样执行6个任务

核心线程执行任务1和2,其它的任务3~6放到队列中
执行完1和2,将3和4从队列中取出执行
执行完3和4,将5和6从队列中取出

    /**
     * LinkedBlockingQueue
     */
    private static void linkedQueue() {
        System.out.println("\n\n =======LinkedBlockingQueue====== \n\n");
        Executor executors = new ThreadPoolExecutor(
                2, 3, 30, TimeUnit.SECONDS,
                new LinkedBlockingQueue(),
                new RejectHandler());
        execute(executors);
    }

运行结果如下:

1 is running... 
2 is running... //中间线程休眠 
2 is end !!!   //10s之后才运行完
1 is end !!! 
3 is running...  //任务3和4才执行
4 is running... 
4 is end !!! 
3 is end !!! 
6 is running... 
5 is running... 
5 is end !!! 
6 is end !!! 

总结

队列 创建线程数 正在可以去有执行意愿(放入到缓存队列和执行线程中)的最多任务数 可以缓存个数
SynchrousQueue maximumPoolSize (corePoolSize+创建的线程数) <=maximumPoolSize
ArrayBlockingQueue maximumPoolSize (corePoolSize+创建的线程数)(相加数要<=maximumPoolSize)+ArrayBlockingQueue设置的缓存数 ArrayBlockingQueue设置的缓存数
LinkedBlockingQueue corePoolSize corePoolSize+LinkedBlockingQueue缓存的无界任务 无界

总的代码如下:

 public static void main(String[] args) {
        queue();  
    }

    /***
     * 执行不同的缓存队列
     */
    private static void queue() {
        syncQueue();
        //arrayQueue();
        //linkedQueue();
    }

    /**
     * ArrayBlockingQueue
     */
    private static void arrayQueue() {
        System.out.println("\n\n =======ArrayBlockingQueue====== \n\n");
        Executor executors = new ThreadPoolExecutor(
                2, 3, 30, TimeUnit.SECONDS,
                new ArrayBlockingQueue(2),
                new RejectHandler());
        execute(executors);
    }

    /**
     * LinkedBlockingQueue
     */
    private static void linkedQueue() {
        System.out.println("\n\n =======LinkedBlockingQueue====== \n\n");
        Executor executors = new ThreadPoolExecutor(
                2, 3, 30, TimeUnit.SECONDS,
                new LinkedBlockingQueue(),
                new RejectHandler());
        execute(executors);
    }

    /**
     * SynchronousQueue
     */
    private static void syncQueue() {
        System.out.println("\n\n =======SynchronousQueue====== \n\n");
        Executor executors = new ThreadPoolExecutor(
                2, 3, 30, TimeUnit.SECONDS,
                new SynchronousQueue(),
                new RejectHandler());
        execute(executors);
    }


    private static void execute(Executor executors) {
        executors.execute(new NameRunnable(1));
        executors.execute(new NameRunnable(2));
        executors.execute(new NameRunnable(3));
        executors.execute(new NameRunnable(4));
        executors.execute(new NameRunnable(5));
        executors.execute(new NameRunnable(6));
    }

 /***
     * 创建一个有名字的runnable对象
     */
    private static class NameRunnable implements Runnable {
        private int name;

        public NameRunnable(int name) {
            this.name = name;
        }

        public int getName() {
            return name;
        }

        @Override
        public void run() {
            System.out.println(name + " is running... ");
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(name + " is end !!! ");
        }
    }

    /***
     * 拒绝的Runnable
     */
    private static class RejectHandler implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            NameRunnable name = (NameRunnable) r;

            System.out.print(name.getName() + " is rejected ^^\n");
        }
    }
}

 

你可能感兴趣的:(Java)