浅析ThreadPoolExecutor

一、一个简单的线程池

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize, //核心线程数
                          long keepAliveTime, //最大线程数
                          TimeUnit unit, //keepAlive的时间
                          BlockingQueue<Runnable> workQueue, //keepAlive的时间的单位
                          ThreadFactory threadFactory, //线程工厂
                          RejectedExecutionHandler handler) { //拒接策略
package com.itheima.security.springboot.threadpool;

import java.util.concurrent.*;

public class MyThreadPool {
    public static void main(String[] args) throws Exception {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                1,
                2,
                50,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(),
                new ThreadFactory() {
                    @Override
                    public Thread newThread(Runnable r) {
                        Thread thread = new Thread(r);
                        thread.setName("天道酬勤");
                        return thread;
                    }
                },
                new ThreadPoolExecutor.AbortPolicy()
        );

        executor.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("哈哈哈,所愿皆所得");
            }
        });

        Future<String> future = executor.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("芝麻开门。。。");
                return "ok";
            }
        });

        System.out.println(future.get());
    }
}

 二、线程池的拒绝策略

  1. 拒绝策略之AbortPolicy
    /**
         * A handler for rejected tasks that throws a
         * {@code RejectedExecutionException}.
         */
        public static class AbortPolicy implements RejectedExecutionHandler {
            /**
             * Creates an {@code AbortPolicy}.
             */
            public AbortPolicy() { }
    
            /**
             * 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) {
                throw new RejectedExecutionException("Task " + r.toString() +
                                                     " rejected from " +
                                                     e.toString());
            }
        }
  2. 拒绝策略之CallerRunsPolicy
     /**
         * A handler for rejected tasks that runs the rejected task
         * directly in the calling thread of the {@code execute} method,
         * unless the executor has been shut down, in which case the task
         * is discarded.
         */
        public static class CallerRunsPolicy implements RejectedExecutionHandler {
            /**
             * Creates a {@code CallerRunsPolicy}.
             */
            public CallerRunsPolicy() { }
    
            /**
             * Executes task r in the caller's thread, unless the executor
             * has been shut down, in which case the task is discarded.
             *
             * @param r the runnable task requested to be executed
             * @param e the executor attempting to execute this task
             */
            public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
                if (!e.isShutdown()) {
                    r.run();
                }
            }
        }
  3. 拒绝策略之DiscardPolicy
    /**
         * A handler for rejected tasks that silently discards the
         * rejected task.
         */
        public static class DiscardPolicy implements RejectedExecutionHandler {
            /**
             * Creates a {@code DiscardPolicy}.
             */
            public DiscardPolicy() { }
    
            /**
             * Does nothing, which has the effect of discarding task r.
             *
             * @param r the runnable task requested to be executed
             * @param e the executor attempting to execute this task
             */
            public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            }
        }
  4. 拒绝策略之DiscardOldestPolicy
    /**
         * A handler for rejected tasks that discards the oldest unhandled
         * request and then retries {@code execute}, unless the executor
         * is shut down, in which case the task is discarded.
         */
        public static class DiscardOldestPolicy implements RejectedExecutionHandler {
            /**
             * Creates a {@code DiscardOldestPolicy} for the given executor.
             */
            public DiscardOldestPolicy() { }
    
            /**
             * Obtains and ignores the next task that the executor
             * would otherwise execute, if one is immediately available,
             * and then retries execution of task r, unless the executor
             * is shut down, in which case task r is instead discarded.
             *
             * @param r the runnable task requested to be executed
             * @param e the executor attempting to execute this task
             */
            public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
                if (!e.isShutdown()) {
                    e.getQueue().poll();
                    e.execute(r);
                }
            }
        }

三、线程池的执行流程 

 四、ThreadPoolExecutor的状态

线程池状态的核心属性ctl

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
//Integer.SIZE =32,COUNT_BITS=29
//ctl表述了两个状态
//1.表示线程池当前的状态(高三位)
//2.表示线程池当前的工作线程个数(低29位)
private static final int COUNT_BITS = Integer.SIZE - 3;
//00100000 00000000 00000000 00000000   ->(1 << COUNT_BITS)
//00011111 11111111 11111111 11111111   ->(1 << COUNT_BITS)-1
//表示线程池工作的最大线程数
private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
// runState is stored in the high-order bits
//线程池的五种状态
//111
private static final int RUNNING    = -1 << COUNT_BITS;
//000
private static final int SHUTDOWN   =  0 << COUNT_BITS;
//001
private static final int STOP       =  1 << COUNT_BITS;
//010
private static final int TIDYING    =  2 << COUNT_BITS;
//011
private static final int TERMINATED =  3 << COUNT_BITS;
// Packing and unpacking ctl
//计算出线程池当前的状态
private static int runStateOf(int c)     { return c & ~CAPACITY; }
//计算出当前线程池中的工作线程数
private static int workerCountOf(int c)  { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }

 

public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
   
    int c = ctl.get();
    //工作线程数是否小于核心线程数
    if (workerCountOf(c) < corePoolSize) {
        //通过ADD方法添加一个核心线程数去执行我们的command
        if (addWorker(command, true))
            //成功返回true
            return;
        //在并发情况下,添加核心线程失败的线程,需要重新获取一起ctl属性
        c = ctl.get();
    }
    //创建核心线程失败,判断当前线程池状态是否是Running
    //如果是running,执行offer方法将任务添加到工作队列
    if (isRunning(c) && workQueue.offer(command)) {
        //添加到工作队列成功
        int recheck = ctl.get();
        if (! isRunning(recheck) && remove(command))
            reject(command);
        //线程池是running状态,判断工作线程是否为0
        else if (workerCountOf(recheck) == 0)
            //工作线程为0,但是工作队列中有任务在排队
            //添加一个空任务非核心线程,处理队列中的任务
            addWorker(null, false);
    }
    //添加到工作队列失败,添加非核心线程去执行当前任务
    else if (!addWorker(command, false))
        //添加非核心线程失败,执行拒绝策略
        reject(command);
}
private boolean addWorker(Runnable firstTask, boolean core) {
		//对线程池状态的判断,对工作线程数量的判断
		//外层for循环的一个标识
        retry:
        for (;;) {
            int c = ctl.get();
			//拿到线程的运行状态
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN &&
				//线程池状态是SHUTDOWN,并且任务为null,并且队列中不为null
				//如果同时满足以上三个要求,那就是要处理工作队列当前任务
                ! (rs == SHUTDOWN &&firstTask == null &&! workQueue.isEmpty()))
                return false;

            for (;;) {
				//获取当前工作线程数量
                int wc = workerCountOf(c);
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                c = ctl.get();  // Re-read ctl
                if (runStateOf(c) != rs)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }
        }

		//添加工作线程并启动
        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
            w = new Worker(firstTask);
            final Thread t = w.thread;
            if (t != null) {
                final ReentrantLock mainLock = this.mainLock;
                mainLock.lock();
                try {
                    // Recheck while holding lock.
                    // Back out on ThreadFactory failure or if
                    // shut down before lock acquired.
                    int rs = runStateOf(ctl.get());

                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        if (t.isAlive()) // precheck that t is startable
                            throw new IllegalThreadStateException();
                        workers.add(w);
                        int s = workers.size();
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值