线程池ThreadPoolExecutor讲解

91 阅读1分钟

构造参数

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)

corePoolSize -线程池中核心线程的数量

maximumPoolSize -线程池中最大线程数 

keepAliveTime -当线程数大于核心,这是多余的空闲线程会等待新的任务终止前的最大时间

unit -keepAliveTime对应的时间单位 

workQueue -工作队列。这个队列将只有 Runnable execute方法提交的任务

threadFactory -工厂用于执行创建新线程 

handler -达到线程边界和队列容量,饱和策略

执行原理

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        //ctl:AtomicInteger,代表线程执行状态,和worker集合数量
        int c = ctl.get();
        //worker集合中线程数小于核心线程数
        if (workerCountOf(c) < corePoolSize) {
            //加入当前任务线程到worker集合,true表示后期有个判断逻辑选择的是corePoolSize
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        //worker集合中线程数不小于核心线程数,且线程是运行状态,将当前线程加入队列中
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (!isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        //worker集合中线程数等于核心线程数,且线程等待队列已满,但是线程数未达到最大线程数,则继续创建工作线程
        //false表示后期有个判断逻辑选择的是maximumPoolSize
        else if (!addWorker(command, false))
            //worker集合中线程数等于核心线程数,且线程等待队列已满,且线程数也达到最大线程数,则执行拒绝策略
            reject(command);
    }

代码事例

public class ThreadHelpController {
    public static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            2, 5, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(5), new MyPolicy());


    public static void main(String[] args) {
        for (int i = 0; i < 11; i++) {
            int a = i;
            Thread thread = new Thread(
                    () -> {
                        System.out.println(a);
                        try {
                            Thread.sleep(10000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
            );
            threadPoolExecutor.execute(thread);
        }

        /**
         * 输出结果:
            1个线程输出:线程池饱和了,拒绝你            5线程输出5个数字
            另外5个线程在工作队列中,等10秒后执行
         */    }

    public static class MyPolicy implements RejectedExecutionHandler {
        /**
         * Creates an {@code AbortPolicy}.
         */
        public MyPolicy() {
        }

        /**
         * Always throws RejectedExecutionException.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         * @throws RejectedExecutionException always
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            System.out.println("线程池饱和了,拒绝你");
        }
    }

}