ThreadPoolExecutor核心方法源码解析

ThreadPoolExecutor核心方法源码解析

前置学习

关于ctl是什么

	private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
 	private static final int COUNT_BITS = Integer.SIZE - 3;
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    // runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    private static final int STOP       =  1 << COUNT_BITS;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;
    private static int workerCountOf(int c)  { return c & CAPACITY; }

ctl 是 当前线程池的状态以及线程数量
对于状态的解释
线程池有5中状态

  • RUNNING
    • 状态说明:线程池处于RUNNING状态时,能够接收新任务以及对已添加的任务进行处理。
    • 状态切换:线程池的初始状态为RUNNING。换句话说线程池一旦被创建,就处于RUNNING状态,且线程池中的任务数为0
      private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
  • SHUTDOWN
    • 状态说明:线程池处于SHUTDOWN状态时,不接收新任务,但能处理已添加的任务
    • 状态切换:调用线程池的shutdown()接口时,线程池由RUNNING->SHUTDOWN
  • STOP
    • 状态说明:线程池处于STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务
    • 状态切换:调用线程池的shutdownNow()接口时,线程池由(RUNNING)或者(SHUTDOWN)->STOP
  • TIDYING
    • 状态说明:当所有的任务已终止,ctl记录的任务数为0,线程池的状态会变为TIDYING状态;当线程池的状态变为TIDYING状态时,会调用钩子函数terminated(),该方法在ThreadPoolExecutor中是空的,若用户想在线程池变为TIDYING时进行相应的处理,就需要重载terminated()函数实现
    • 状态切换:当线程池状态为SHUTDOWN时,阻塞队列为空并且线程池中执行的任务也为空时,就会由SHUTDOWN->TIDYING
      当线程池为STOP时,线程池中执行的任务为空时,就会又STOP->TIDYING
  • TERMINATED
    • 状态说明:线程池彻底终止,就会变成TERMINATED状态
    • 状态切换:线程池处于TIDYING状态时,调用terminated()就会由TIDYING->TERMINATED

状态的计算规则

上述代码中可以看到
RUNNING状态是 -1 << COUNT_BITS,其中COUNT_BITS为29,因为 SIZE = 32;因此RUNNING左移过程为
-1的原码 10000 0000 0000 0000 0000 0000 0000 0001
-1的反码 1111 1111 1111 1111 1111 1111 1111 1110
-1的补码 1111 1111 1111 1111 1111 1111 1111 1111
因此-1左移29位为 1110 0000 0000 0000 0000 0000 0000 0000

SHUTDOWN是 0 << COUNT_BITS,
0左移29位为0000 0000 0000 0000 0000 0000 0000 0000
同理
STOP 0010 0000 0000 0000 0000 0000 0000 0000
TIDYING 0100 0000 0000 0000 0000 0000 0000 0000
TERMINATED 0110 0000 0000 0000 0000 0000 0000 0000

这样就只有RUNNING状态是负数

workerCountOf用于获取工作线程的数量

c & CAPACITY

其中
CAPACITY为 (1 << COUNT_BITS) - 1
1左移29位减1
1<<29 0010 0000 0000 0000 0000 0000 0000 0000
再-1 为 0001 1111 1111 1111 1111 1111 1111 1111
和 c(这里保存了线程池的运行状态和线程的数量)&
这样就去掉了线程池的状态

execte方法解析

public void execute(Runnable command) {
		//判断是否为null,如果是则抛出异常
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        //判断线程数量是否小于核心线程数量
        //如果小于则创建一个核心工作线程
        if (workerCountOf(c) < corePoolSize) {
        	//创建一个核心工作线程
        	//成功则直接返回
            if (addWorker(command, true))
                return;
              //再次获取c,目的是为了获取线程池的状态
            c = ctl.get();
        }
        //判断是否是运行状态并且是否将任务添加到队列
        if (isRunning(c) && workQueue.offer(command)) {
        	//再次获取c
            int recheck = ctl.get();
            //如果线程不是运行状态并且从队列中移除了当前任务
            if (! isRunning(recheck) && remove(command))
            	//拒绝任务
                reject(command);
              //如果线程池中的工作线程为0
            else if (workerCountOf(recheck) == 0)
            	//创建一个非核心线程
                addWorker(null, false);
        }
        //添加非核心工作线程
        //如果添加非核心工作线程失败
        else if (!addWorker(command, false))
        	//拒绝当前的任务
            reject(command);
    }

这里可以看到调用了好多次 addWorker() 方法,主要是用于增加工作线程(true为核心线程,false为非核心线程),接下来继续分析addWorker

addWorker()方法解析

//第一个参数为需要执行的任务,第二个参数为是否为核心线程
private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            //这个主要是看队列是否为空的,如果队列为空则直接返回,如果状态值大于等于SHUTDOWN也直接返回
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
            	//获取工作线程的数量
                int wc = workerCountOf(c);
                //如果线程数量大于等于最大线程数量,即已经满了,或者如果是核心线程,就判断是否大于等于设置的核心线程数量,如果是非核心线程,就判断是否大于等于设置的最大线程数量
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                 //先给线程数量加1,这里使用的CAS给线程数量加1
                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 {
                   //获取线程池状态
                    int rs = runStateOf(ctl.get());
					
                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        //判断线程是否存活
                        if (t.isAlive()) 
                            throw new IllegalThreadStateException();
                        //添加woker到workers中(workders是一个HashSet)
                        workers.add(w);
                        //获取工作线程数量
                        int s = workers.size();
                        //更新最后线程数量
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                         //这里是添加worker完成
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                //添加完成则启动线程
                if (workerAdded) {
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }

线程启动后调用run方法,然后调用 runWorker()方法

runWorker()方法解析

 final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        //允许中断
        w.unlock(); // allow interrupts
        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);
                    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);
                    }
                } finally {
                	//给任务赋空
                    task = null;
                    w.completedTasks++;
                    w.unlock();
                }
            }
            completedAbruptly = false;
        } finally {
            processWorkerExit(w, completedAbruptly);
        }
    }

getTask() 方法解析

private Runnable getTask() {
		// Did the last poll() time out?
		//用于记录上次的轮询是否超时
        boolean timedOut = false; 

        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            //如果线程池不是运行状态,并且线程池的状态大于stop或者队列是空的
            //则直接给workers减一,并且返回null
            //在runWworker中可能会退出循环
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
                decrementWorkerCount();
                return null;
            }

            int wc = workerCountOf(c);

            // Are workers subject to culling?
            //是否允许核心线程超时,或者工作线程的数量大于核心线程的数量
            //就是看当前这个线程会不会被干掉
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
			//如果工作线程大于最大线程数并且轮询超时并且允许被干掉
			//并且有工作线程或者队列是空的
            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {
                //安全的减去一个线程
                if (compareAndDecrementWorkerCount(c))
                    return null;
                continue;
            }

            try {
            	//从队列中获取任务
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }

processWorkerExit() work退出流程解析

 private void processWorkerExit(Worker w, boolean completedAbruptly) {
 		//如果是突然的,就不调整worker
 		// If abrupt, then workerCount wasn't adjusted
 		//这里是先给worker减一,然后最后再添加一个非核心worker
        if (completedAbruptly)  
            decrementWorkerCount();

        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            completedTaskCount += w.completedTasks;
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }
		//尝试去终止线程池
        tryTerminate();

        int c = ctl.get();
        //判断最后的状态是不是小于stop,
        //即可能有两个状态  run,以及SHUTDOWN
        if (runStateLessThan(c, STOP)) {
        	//如果不是突然的或者异常的
            if (!completedAbruptly) {
            	//看是否允许核心线程超时
            	//是则取0 否则取核心线程数
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                //如果队列不为并且min为0
                //则认为还需要处理,给min赋为1
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                //判断工作线程的数量是否大于等于min
                //上面min赋值为1,就是为了保证队列不空的时候有线程去处理队列
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            //上面如果是异常终止的线程,则添加一个新的非核心线程到workers中
            addWorker(null, false);
        }
    }

tryTerminate() 解析

尝试去终止线程池,这个是尝试将线程池的状态修改为TERMINATED

final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            //如果线程池是运行状态或者最后的状态大于等于TIDYING或者 状态为SHUTDOWN 并且队列不为空,则直接返回
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
                return;
            // Eligible to terminate
            //如果还有工作线程则中断一个空闲的线程,然后返回
            if (workerCountOf(c) != 0) { 
                interruptIdleWorkers(ONLY_ONE);
                return;
            }
			//走到这里则认为,线程池中没有线程了,可以修改
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                    	//钩子函数用于终止前的处理
                        terminated();
                    } finally {
                    	//设置状态为TERMINATED
                        ctl.set(ctlOf(TERMINATED, 0));
                        //唤醒调用awaitTermination()的线程
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

interruptIdleWorkers() 中断空闲线程方法解析

 private void interruptIdleWorkers(boolean onlyOne) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
        	//遍历所有线程
            for (Worker w : workers) {
                Thread t = w.thread;
                //如果没有中断并且可以获取到锁
                if (!t.isInterrupted() && w.tryLock()) {
                    try {
                    	//中断线程
                        t.interrupt();
                    } catch (SecurityException ignore) {
                    } finally {
                        w.unlock();
                    }
                }
                //如果只有一个,则返回
                if (onlyOne)
                    break;
            }
        } finally {
            mainLock.unlock();
        }
    }

shutdown() 解析

    public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
        	//检查权限
            checkShutdownAccess();
            //修改线程池的运行状态
            advanceRunState(SHUTDOWN);
            //中断空闲线程
            interruptIdleWorkers();
            //钩子函数,用于自己调用shutdown后的操作
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        //尝试去终止
        tryTerminate();
    }

shutdownNow() 立即shutdown

    public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(STOP);
            //中断所有的线程
            interruptWorkers();
            //将剩余的任务拿出来,返回
            tasks = drainQueue();
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
        return tasks;
    }

interruptWorkers()

    private void interruptWorkers() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers)
                w.interruptIfStarted();
        } finally {
            mainLock.unlock();
        }
    }

interruptIfStarted()

void interruptIfStarted() {
            Thread t;
            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
                try {
                    t.interrupt();
                } catch (SecurityException ignore) {
                }
            }
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龘龍龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值