线程池ThreadPoolExecutor源码

基本概念

构造参数

  • corePoolSize:核心线程数量
  • maximumPoolSize:最大线程数量
  • allowCoreThreadTimeOut:是否允许线程超时(设置为true时与keepAliveTime,TimeUnit一起起作用)
  • keepAliveTime:线程存活时间(当线程池允许线程超时且运行中的线程数量超过corePoolSize时,会按照此变量设置时间关闭线程)
  • TimeUnit:单位(一般与keepAliveTime同时使用,供线程池判断是否满足关闭线程的条件)
  • workQueue:缓冲阻塞队列
  • RejectedExecutionHandler:拒绝处理任务类(默认:ThreadPoolExecutor.AbortPolicy 会抛异常,见下方实例)
  • threadFactory:线程工厂(默认:DefaultThreadFactory)

线程池的五种状态:

  • RUNNING - 接受新任务并且继续处理阻塞队列中的任务
  • SHUTDOWN - 不接受新任务但是会继续处理阻塞队列中的任务
  • STOP - 不接受新任务,不在执行阻塞队列中的任务,中断正在执行的任务
  • TIDYING - 所有任务都已经完成,线程数都被回收,线程会转到TIDYING状态会继续执行钩子方法 将执行terminated()方法
  • TERMINATED - 结束态,terminated() 方法已完成

流程图

execute方法

Created with Raphaël 2.2.0 execute方法 核心线程是否未满? 创建启动worker并添加到workers中 队列是否未满? queue中添加task 是否未到做大线程数? 走拒绝策略 yes no yes no yes no

runWorker方法

Created with Raphaël 2.2.0 runWorker方法 是否有超时时间或工作线程数大于核心线程数? 阻塞队列中等待keepAliveTime时间是否有任务? 队列中取出任务执行 当前worker 退出 队列中是否有任务? 当前worker block yes no yes no yes no

debug代码如下

package cha.pao.fan.blogs.thread;

import java.util.concurrent.*;

public class ThreadPoolTest {
    // 核心线程数量
    private static int corePoolSize = 2;
    // 最大线程数量
    private static int maxPoolSize = 3;
    // 线程存活时间:当线程数量超过corePoolSize时,10秒钟空闲即关闭线程
    private static int keepAliveTime = 10000;
    // 缓冲队列
    private static BlockingQueue<Runnable> workQueue  = new LinkedBlockingQueue<Runnable>(5);
    // 线程池
    private static ThreadPoolExecutor threadPoolExecutor = null;

    private static ThreadFactory threadFactory=new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r,r+"--chang");
        }
    };
    private static RejectedExecutionHandler rejectedExecutionHandler=new ThreadPoolExecutor.AbortPolicy();



    static {
        threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS,
                workQueue,threadFactory,rejectedExecutionHandler){
            @Override
            protected void terminated() {
                System.out.println("=====================is over==============");
            }
        };
    }

    public static void main(String[] args) throws InterruptedException {
            for (int i = 0; i < 200; i++) {
                try{
                    threadPoolExecutor.execute(new MyTask());
                    System.out.println("线程池中正在执行的线程数量:" + threadPoolExecutor.getPoolSize());
                    System.out.println("线程池缓存的任务队列数量:" + threadPoolExecutor.getQueue().size());
                }catch (Throwable e){

                }

            }
        threadPoolExecutor.shutdown();
    }
}

class MyTask implements Runnable {
    @Override
    public void run() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(this.toString());
    }
}


private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    private static final int COUNT_BITS = Integer.SIZE - 3;//高三位 线程池状态,低29位 线程数量
    private static final int COUNT_MASK = (1 << COUNT_BITS) - 1;//低29位遮罩 11111111111111111111111111111  

    // runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;//-536870912
    private static final int SHUTDOWN   =  0 << COUNT_BITS;//0
    private static final int STOP       =  1 << COUNT_BITS;//536870912
    private static final int TIDYING    =  2 << COUNT_BITS;//1073741824
    private static final int TERMINATED =  3 << COUNT_BITS;//1610612736

    // Packing and unpacking ctl
    private static int runStateOf(int c)     { return c & ~COUNT_MASK; }//前29位取反为0,升下的值就是 线程的状态码
    private static int workerCountOf(int c)  { return c & COUNT_MASK; }//前29位值来存储 线程数
    private static int ctlOf(int rs, int wc) { return rs | wc; }

    /*
     * Bit field accessors that don't require unpacking ctl.
     * These depend on the bit layout and on workerCount being never negative.
     */

    private static boolean runStateLessThan(int c, int s) {
        return c < s;
    }

    private static boolean runStateAtLeast(int c, int s) {
        return c >= s;
    }

    private static boolean isRunning(int c) {
        return c < SHUTDOWN;
    }

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        /*
         * Proceed in 3 steps:
         *
         * 1. If fewer than corePoolSize threads are running, try to
         * start a new thread with the given command as its first
         * task.  The call to addWorker atomically checks runState and
         * workerCount, and so prevents false alarms that would add
         * threads when it shouldn't, by returning false.
         *
         * 2. If a task can be successfully queued, then we still need
         * to double-check whether we should have added a thread
         * (because existing ones died since last checking) or that
         * the pool shut down since entry into this method. So we
         * recheck state and if necessary roll back the enqueuing if
         * stopped, or start a new thread if there are none.
         *
         * 3. If we cannot queue task, then we try to add a new
         * thread.  If it fails, we know we are shut down or saturated
         * and so reject the task.
         */
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))//如果小于核心线程数,直接增加worker,返回
                return;
            c = ctl.get();
        }//达到核心线程数,时走如下逻辑
        if (isRunning(c) && workQueue.offer(command)) {//判断是否正在执行,并且尝试往队列中添加worker
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))//再次检查状态
                reject(command);
            else if (workerCountOf(recheck) == 0)//workercount为零时
                addWorker(null, false);
        }
        else if (!addWorker(command, false))//核心线程已满,队列也已满,向maxPoolSize扩容,扩容失败 走拒绝策略
            reject(command);
    }
private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
                int wc = workerCountOf(c);
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))//非核心线程 超过max线程数,返回false添加失败,并景区reject策略
                    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);//新建worker对象
            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();//启动worker封装的任务,调用Worker 的runWorker方法
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }
private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable
    {
        /**
         * This class will never be serialized, but we provide a
         * serialVersionUID to suppress a javac warning.
         */
        private static final long serialVersionUID = 6138294804551838833L;

        /** Thread this worker is running in.  Null if factory fails. */
        final Thread thread;
        /** Initial task to run.  Possibly null. */
        Runnable firstTask;
        /** Per-thread task counter */
        volatile long completedTasks;

        /**
         * Creates with given first task and thread from ThreadFactory.
         * @param firstTask the first task (null if none)
         */
        Worker(Runnable firstTask) {
            setState(-1); // aqs设置state为-1,后边可以检查中断先unlock一次
            this.firstTask = firstTask;//任务设置为firstTask
            this.thread = getThreadFactory().newThread(this);//把firstTask封装成Worker对象
        }

        /** Delegates main run loop to outer runWorker  */
        public void run() {
            runWorker(this);
        }

        // Lock methods
        //
        // The value 0 represents the unlocked state.
        // The value 1 represents the locked state.

        protected boolean isHeldExclusively() {
            return getState() != 0;
        }

        protected boolean tryAcquire(int unused) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());//设置当前线程独占资源
                return true;
            }
            return false;
        }

        protected boolean tryRelease(int unused) {
            setExclusiveOwnerThread(null);//释放资源
            setState(0);
            return true;
        }

        public void lock()        { acquire(1); }
        public boolean tryLock()  { return tryAcquire(1); }
        public void unlock()      { release(1); }
        public boolean isLocked() { return isHeldExclusively(); }

        void interruptIfStarted() {
            Thread t;
            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
                try {
                    t.interrupt();
                } catch (SecurityException ignore) {
                }
            }
        }
    }
final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();//worker线程
        Runnable task = w.firstTask;//传入的task
        w.firstTask = null;//task致空
        w.unlock(); // worker初始化资源是-1,这里unlock后  state变为0,同时检查线程是否中断
        boolean completedAbruptly = true;
        try {
            while (task != null || (task = getTask()) != null) {//这里是个循环一个任务执行完后,重队列中取另一个任务
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted.  This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    wt.interrupt();
                try {
                    beforeExecute(wt, task);//执行任务前 做些处理,可以重写 ThreadPoolExecutor的beforeExecute方法
                    Throwable thrown = null;
                    try {
                        task.run();//执行任务
                    } catch (RuntimeException x) {
                        thrown = x; throw x;
                    } catch (Error x) {
                        thrown = x; throw x;
                    } catch (Throwable x) {
                        thrown = x; throw new Error(x);
                    } finally {
                        afterExecute(task, thrown);//执行任务前 做些处理,可以重写 ThreadPoolExecutor的afterExecute方法
                    }
                } finally {
                    task = null;
                    w.completedTasks++;//worker执行任务次数+1
                    w.unlock();//解锁当前workker
                }
            }
            completedAbruptly = false;
        } finally {
            processWorkerExit(w, completedAbruptly);//线程退出前走这里
        }
    }
private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

        for (;;) {//通过循环 处理 最大线程 到核心线程的缩容操作
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }

            int wc = workerCountOf(c);

            // Are workers subject to culling?
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;//如果设置超时,或者当前worker数大于corepoolsize,timeed=true  这里注意如果wc小于corepoolsize timed肯定为false,后面在workQueue取任务时 肯定时workQueue.take(),这时候就可能block,所以线程即使没有任务执行 时不会空跑的

            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {//大于核心线程数  这里会结束当前线程
                if (compareAndDecrementWorkerCount(c))//cas操作,如果多线程处理,只会有一个成功,失败的 会继续再一次循环
                    return null;
                continue;
            }

            try {
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) ://尝试在超时时间内重队列头部移除元素并返回  keepAliveTime这个参数的用法关键就在这里
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;//第一次,如果超时时间内没返回任务,说明当前worker 等待keepAliveTime时间,返回null,在调用方法里面处理
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }
    ```
    
```java


private void processWorkerExit(Worker w, boolean completedAbruptly) {
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
            decrementWorkerCount();

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            completedTaskCount += w.completedTasks;
            workers.remove(w);//移除工作队列
        } finally {
            mainLock.unlock();
        }

        tryTerminate();

        int c = ctl.get();
        if (runStateLessThan(c, STOP)) {
            if (!completedAbruptly) {
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            addWorker(null, false);
        }
    }
final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            if (isRunning(c) ||// 线程池的运行状态为RUNNING
                runStateAtLeast(c, TIDYING) ||//线程池运行状态最小要大于TIDYING
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))//线程池的运行状态为SHUTDOWN并且workQueue队列不为null
                return;
            if (workerCountOf(c) != 0) { // Eligible to terminate
                interruptIdleWorkers(ONLY_ONE);
                return;
            }

            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        terminated();//执行到这里所有线程一定全部执行完成
                    } finally {
                        ctl.set(ctlOf(TERMINATED, 0));
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值