ThreadPoolExecutor --- 线程池源码分析

本文详细剖析了Java并发工具类`ThreadPoolExecutor`的内部工作机制,包括其核心成员变量、构造方法、execute方法、线程池状态管理、线程的创建与销毁以及任务调度策略。通过对源码的解读,揭示了线程池如何处理任务提交、线程数量控制、拒绝策略等关键逻辑,帮助读者深入理解Java多线程编程。
摘要由CSDN通过智能技术生成

首先看到ThreadPoolExecutor类中的一些成员变量

	//ctl 初始为 RUNNING 且 线程池中没有线程  111+29个0  
	private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
	//COUNT_BITS 32 - 3 = 29
    private static final int COUNT_BITS = Integer.SIZE - 3; 
    //线程池最大容量 前3位为0 后29位为1
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    //使用高三位来表示线程池的状态  RUNNING为负数,最小
    private static final int RUNNING    = -1 << COUNT_BITS;  //111 
    //不接受新任务,能执行阻塞队列的任务
    private static final int SHUTDOWN   =  0 << COUNT_BITS;  //000
    //不接受新任务,丢弃阻塞队列的任务 ,   ctl大于等于STOP 则表示线程池要GG了  
    private static final int STOP       =  1 << COUNT_BITS;  //001
    //线程池中没有任务要执行了,线程也都死亡了
    private static final int TIDYING    =  2 << COUNT_BITS;  //010
    //线程池终结了
    private static final int TERMINATED =  3 << COUNT_BITS;  //011

    //线程池的运行状态 --- CAPACITY取反,则前3位为1 后29位为0 ,使用参数进行与运算, 显然只取前3位的值
    private static int runStateOf(int c)     { return c & ~CAPACITY; }
    //线程池中的线程数量 --- CAPACITY 前3位位0 后29位为1 使用参数进行与预算 显然只取后29位的值 
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    //或运算
    private static int ctlOf(int rs, int wc) { return rs | wc; }
    //线程池是否处于运行状态
	private static boolean isRunning(int c) {return c < SHUTDOWN;}
	private static boolean runStateLessThan(int c, int s) {return c < s;}
    private static boolean runStateAtLeast(int c, int s) {return c >= s;}

再看下构造方法

	public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        //核心线程数        
        this.corePoolSize = corePoolSize;  
        //最大线程数     
        this.maximumPoolSize = maximumPoolSize;
        //阻塞队列
        this.workQueue = workQueue;
        //空闲线程存活时间
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        //生成线程的线程工厂 最好使用自己的实现的, 一般用来给线程取名字 , 便于快速定位问题
        this.threadFactory = threadFactory;
        //拒绝策略 最好使用自己的实现的, 可以进行告警通知 
        this.handler = handler;
    }

看到execute方法

	public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        //获取ctl的值 
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
        	//如果线程池的线程数量小于核心线程数
        	//向线程池中添加任务,并运行任务,成功则返回true , 则 return ,则execute方法结束
            if (addWorker(command, true))
                return;
            //上面失败了,可能是核心线程被其他线程抢到了导致核心线程不够用了 , 也可能是线程池被关闭了
            c = ctl.get();
        }
        //如果线程池在运行状态 且 任务放入阻塞队列成功
        if (isRunning(c) && workQueue.offer(command)) {
        	//再次获取ctl的值
            int recheck = ctl.get();
            //如果线程池需要关闭 且 从队列中移除该任务成功
            if (! isRunning(recheck) && remove(command))
            	//调用RejectedExecutionHandler 的rejectedExecution方法 ,拒绝策略
                reject(command);
            //走到这里 则说明线程池在运行状态 或者 队列中的任务已经被其他线程取走
            //如果池中线程数为0
            else if (workerCountOf(recheck) == 0)
            	//新创建一个worker来执行任务
                addWorker(null, false);
        }
        //线程池需要关闭 或者 阻塞队列入队失败(容量不够)
        //再次调用addWorker(阻塞队列中有任务可能刚好被拿出来执行了)
        else if (!addWorker(command, false))
        	//拒绝
            reject(command);
    }
    
	public boolean remove(Runnable task) {
		//从队列中移除该任务
        boolean removed = workQueue.remove(task);
        //尝试终结线程池
        tryTerminate(); // In case SHUTDOWN and now empty
        //返回是否移除任务成功
        return removed;
    }

addWorker方法

	private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            //获取线程池状态
            int rs = runStateOf(c);

			//rs >= SHUTDOWN  , 线程池不是运行状态    且
			// !     (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty()) 
			// 正处于SHUTDOWN状态 且 传进来的任务为空 且 阻塞队列不为空 (需要处理完阻塞队列的任务)			 
			//然后对上面整个一行的条件的 ! 
			//说明,线程池要关了 ,不接受新任务了 ,阻塞队列中没有需要处理的任务 则这里直接返回false 
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;
			
			//线程池处于运行状态 或者 线程池正处于SHUTDOWN状态 需要去执行完阻塞队列中的任务
            for (;;) {
            	//获取线程池中线程的数量
                int wc = workerCountOf(c);
                //大于等于最大数量 
                //或者    根据入参core判断  大于等于核心线程数或者大于等于最大线程数
                //以上成立,则返回false
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                //上面的条件不成立,则说明可以创建线程来执行任务
                //对ctl cas 加一 , 表示线程数量+1 
                //cas成功则跳出循环 , 失败 则继续循环
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                //cas失败,被其他线程修改了,则重新获取ctl的值
                c = ctl.get();  // Re-read ctl
                //cas失败有可能线程池要被关闭了 如果线程池运行状态不为rs(运行状态), 则跳出内层循环
                if (runStateOf(c) != rs)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }
        }
		
		//走到这里, 则 说明cas 修改 ctl成功
		//或者 线程池要被关闭

        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
        	//将任务包装为Worker
            w = new Worker(firstTask);
            //获取到线程工厂的创建的线程
            final Thread t = w.thread;
            if (t != null) {
                final ReentrantLock mainLock = this.mainLock;
                //加锁
                mainLock.lock();
                try {
					//再次获取ctl的值
                    int rs = runStateOf(ctl.get());
					
					//rs < SHUTDOW , 则只能是 RUNNING  运行状态
					//或者  (rs == SHUTDOWN && firstTask == null) 线程池正在关闭中且入参firstTask为空,则需要去执行阻塞队列的任务
                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        //如果线程已经被start了,抛异常
                        if (t.isAlive()) // precheck that t is startable
                            throw new IllegalThreadStateException();
                        //将Worker加入到workers中
                        workers.add(w);
                        //获取工作线程数量
                        int s = workers.size();
                        //如果工作线程数量大于largestPoolSize  largestPoolSize改为该值
                        //显然largestPoolSize 用来记录整个线程池运行过程中达到过的最大线程数
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                    //如果线程刚好被关闭了,则上面判断判断不成立,workerAdded 为false
                } finally {
                    mainLock.unlock();
                }
                //如果workerAdded为false,则这里不会走, workerStarted也为false
                if (workerAdded) {
                	//看到Worker的run方法
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
        	//如果workerStarted为false
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }

	//线程池被关了,无法添加新的任务
	private void addWorkerFailed(Worker w) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            if (w != null)
            	//还Worker没被执行,从workers中移除
                workers.remove(w);
            //对ctl cas 减一 , 表示线程数量少了一个 
            decrementWorkerCount();
            //尝试将线程池状态修改为TERMINATED 
            tryTerminate();
        } finally {
            mainLock.unlock();
        }
    }

ThreadPoolExecutor的Worker类,本身也实现了Runnable接口 ,也继承了aqs,可以进行加解锁操作

	    //构造方法
	    Worker(Runnable firstTask) {
	    	//直接设置state成-1, 显然Worker刚被new出来时,就是加锁状态
	    	//直到worker运行到runWorker方法,才会执行一次unlock方法,将state修改为0
            setState(-1); // inhibit interrupts until runWorker
            //firstTask 使用户的Runnable 
            this.firstTask = firstTask;
            //thread是用Worker创建的线程
            this.thread = getThreadFactory().newThread(this);
        }
        
        //显然Worker不支持重入
        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;
        }
        
        //重写Runnable接口的run方法
        public void run() {
            runWorker(this);
        }
        final void runWorker(Worker w) {
	        Thread wt = Thread.currentThread();
	        //获取到任务
	        Runnable task = w.firstTask;
	        //help gc 
	        w.firstTask = null; 
	        //worker解锁
	        w.unlock(); // allow interrupts
	        boolean completedAbruptly = true;
	        try {
	        	//如果task不为空,或者从队列中获取的任务不为空(getTask方法拿不到任务会阻塞,所以线程池不关闭的情况下,核心线程只是被阻塞了,不会死亡(如果设置了核心线程超时死亡的话,还是会死亡))
	            while (task != null || (task = getTask()) != null) {
	            	//加锁
	                w.lock();
	                //(线程池为STOP或TIDYING或TERMINATED 或者 (线程被中断了(重置中断标识为false)且线程池为STOP或TIDYING或TERMINATED))
	                // 且线程中断标识不为true
	                if ((runStateAtLeast(ctl.get(), STOP) ||
	                     (Thread.interrupted() &&
	                      runStateAtLeast(ctl.get(), STOP))) &&
	                    !wt.isInterrupted())
	                    //执行中断 ,中断标志位设置为true
	                    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 置空
	                    task = null;
	                    //完成的任务数加一
	                    w.completedTasks++;
	                    //解锁
	                    w.unlock();
	                }
	            }
	            //while正常跳出 , 修改completedAbruptly 为false 
	            //while中抛出异常则这里执行不到 completedAbruptly 为true
	            completedAbruptly = false;
	        } finally {
	        	//看这里,while出来后,代表该线程要从线程池中移除
	            processWorkerExit(w, completedAbruptly);
	        }
        }

tryTerminate方法

	final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            //如果线程池处于运行状态 
            //或者ctl大于等于TIDYING,也就是线程池已经要GG了
            //或者线程池为SHUTDOWN 且 阻塞队列还有任务需要执行
            //则该方法直接返回
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
                return;
            //如果线程池中的线程数量不为0
            if (workerCountOf(c) != 0) { // Eligible to terminate
            	//打断这些线程,ONLY_ONE为true 
                interruptIdleWorkers(ONLY_ONE);  
                //然后该方法直接返回
                return;
            }
			
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
            	//将ctl cas修改为TIDYING
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                    	//修改成功,则调用terminated,不过是个空方法,子类可以去重写它
                        terminated();
                    } finally {
                    	//将ctl修改为TERMINATED状态
                        ctl.set(ctlOf(TERMINATED, 0));
                        //唤醒termination条件队列中等待的线程
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }
	private void interruptIdleWorkers(boolean onlyOne) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (Worker w : workers) {
                Thread t = w.thread;
                //线程没有被打断过,然后尝试加锁(worker在执行任务时加了锁,不能去打断在执行任务的worker)
                if (!t.isInterrupted() && w.tryLock()) {
                    try {
                    	//打断线程
                        t.interrupt();
                    } catch (SecurityException ignore) {
                    } finally {
                        w.unlock();
                    }
                }
                //如果为true,只尝试中断一个线程就跳出
                if (onlyOne)
                    break;
            }
        } finally {
            mainLock.unlock();
        }
    }
    //该方法用去阻塞调用线程  等待线程池终结完毕
    public boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException {
        long nanos = unit.toNanos(timeout);
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            for (;;) {
            	//已经终结了  返回true 
                if (runStateAtLeast(ctl.get(), TERMINATED))
                    return true;
                if (nanos <= 0)
                    return false;
                //进入条件等待队列中
                nanos = termination.awaitNanos(nanos);
            }
        } finally {
            mainLock.unlock();
        }
    }

getTask方法

    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.
            //如果线程池被关闭,且 (不是SHUTDOWN状态 或者 阻塞队列没有任务)
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
            	//将ctl cas减一 表示线程池中线程数量减一
                decrementWorkerCount(); 
                return null;
            }
			
			//获取线程池中的线程数
            int wc = workerCountOf(c);
			
            // Are workers subject to culling?
            //allowCoreThreadTimeOut 是否允许核心线程超时,默认为false,可以使用allowCoreThreadTimeOut方法修改
            //wc > corePoolSize 线程数是否大于核心线程数,大于的话,则会超时,则不作为核心线程,可以超时回收
            boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
			
			//( 如果线程数大于最大线程数 或者 超时 ) 且 (线程数大于1,或者阻塞队列为空)
            if ((wc > maximumPoolSize || (timed && timedOut))
                && (wc > 1 || workQueue.isEmpty())) {
                //将ctl cas减一 表示线程池中线程数量减一
                if (compareAndDecrementWorkerCount(c))
                    return null;
                //cas失败执行下一次循环
                continue;
            }
			
            try {
            	//是否允许超时回收
            	//从队列中获取任务,会阻塞 , workQueue为构造函数出入进来的阻塞队列
            	//take和poll被中断则导致抛出中断异常
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                	//返回获取任务
                    return r;
                //超时没有获取到任务,修改 timedOut 为true , 下次循环(timed && timedOut)则会成立,则有可能return null,然后被回收
                timedOut = true;
            } catch (InterruptedException retry) {
            	//响应中断异常,重新下一次循环
                timedOut = false;
            }
        }
    }

processWorkerExit方法

    private void processWorkerExit(Worker w, boolean completedAbruptly) {
    	//如果true,则该线程执行任务时发生异常,该线程需要死亡了
        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
        	//ctl cas扣减1  线程数量减一 
            decrementWorkerCount();
		
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
        	//completedTaskCount 汇总worker完成任务的数量
            completedTaskCount += w.completedTasks;
            //将worker从workers移除,gc则可以回收该worker
            workers.remove(w);
        } finally {
            mainLock.unlock();
        }
		
		//尝试将线程池状态修改为TERMINATED 
        tryTerminate();
		
        int c = ctl.get();
        //如果ctl小于STOP ,则是 RUNNING 或者 SHUTDOWN ,执行下面代码
        if (runStateLessThan(c, STOP)) {
        	//如果completedAbruptly 为 false
            if (!completedAbruptly) {
            	//是否允许核心线程超时
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                //允许核心线程超时 且 阻塞队列不为空 ,至少需要一个线程来执行阻塞队列的任务
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                //如果线程数大于等于min,直接返回
                if (workerCountOf(c) >= min)
                    return; // replacement not needed
            }
            //如果completedAbruptly 为 true (异常导致死亡的线程)
            //则可能需要新建一个worker来补充  
            addWorker(null, false);
        }
    }

看到shutdown方法

	public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            //将线程池状态改为SHUTDOWN
            advanceRunState(SHUTDOWN);
            //中断空闲线程
            interruptIdleWorkers();
            //提供给子类实现
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        //尝试终结线程池
        tryTerminate();
    }
    private void advanceRunState(int targetState) {
        for (;;) {
            int c = ctl.get();
            //如果ctl大于等于targetState 直接break (不能把状态往更小的值改,比如TERMINATED改成其他状态)
            if (runStateAtLeast(c, targetState) ||
            	//将ctl cas 修改为   (  ctlOf(targetState, workerCountOf(c))  保留了后29位不变(线程数量不能改),对targetState的前3位和000进行或运算 (只修改线程池状态))
                ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
                break;
        }
    }
    private void interruptIdleWorkers() {
    	//false,循环所有的workers去尝试中断,
        interruptIdleWorkers(false);
    }

到此,ThreadPoolExecutor 源码解析就结束了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值