线程池execute方法的源码解析

本文是线程池execute方法的源码,在此之前可以先看下【线程池的创建】

ThreadPoolExecutor中execute方法

newCachedThreadPool、newFixedThreadPool、newSingleThreadExecutor的execute方法在ThreadPoolExecutor中。

1)、顶层入口;

package java.util.concurrent;
public interface Executor {

    void execute(Runnable command);
}

2)、ExecutorService,线程池真正的接口;

    package java.util.concurrent;
    public interface ExecutorService extends Executor {
        //与本文讲解的execute关系不大,省略
    }

 3)、AbstractExecutorService ,ExecutorService的实现类,使用了abstract修饰,只实现了ExecutorService接口中部分接口;

package java.util.concurrent;
public abstract class AbstractExecutorService implements ExecutorService {
    //与本文讲解的execute关系不大,省略
}

4)、ThreadPoolExecutor,继承了AbstractExecutorService类,包含execute方法;

package java.util.concurrent;
public class ThreadPoolExecutor extends AbstractExecutorService {
   
    //ctl包含线程池的运行状态(高3位)和有效线程数信息(低29位)
    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    //有效线程数所占位数(29)
    private static final int COUNT_BITS = Integer.SIZE - 3;
    //理论上有效线程数的最大值
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    /**线程池运行状态*/
    //线程池能够处理新任务,并且处理队列任务
    private static final int RUNNING    = -1 << COUNT_BITS;
    //线程池不接受新任务,但是会处理队列任务
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    //线程池不接受新任务,也不处理队列任务,会中断进行中的任务
    private static final int STOP       =  1 << COUNT_BITS;
    //线程池中所有任务结束,有效线程数为0
    private static final int TIDYING    =  2 << COUNT_BITS;
    //线程池完成状态
    private static final int TERMINATED =  3 << COUNT_BITS;

    //从ctl中解析出线程池运行状态的方法
    private static int runStateOf(int c)     { return c & ~CAPACITY; }
    //从ctl中解析出有效线程数的方法
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    //ctl的初始化方法
    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) {//有效线程数小于核心线程数
            if (addWorker(command, true))//添加有效(核心)线程
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {//有效线程数不小于核心线程数,检查线程池是否是RUNNING状态;是,将任务对象添加到任务队列中
            int recheck = ctl.get();//再次获取线程池的运行状态和有效线程数
            if (! isRunning(recheck) && remove(command))
                reject(command);//当前线程池不处于RUNNING状态,移除任务队列workQueue中的任务对象,并执行拒绝策略
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);//当前线程池中的worker数为0,则直接创建一个(非核心)线程,task为空的线程在执行时,会直接到任务队列中去获取任务
        }
        else if (!addWorker(command, false))
            reject(command);//将任务对象添加到任务队列中失败,则添加到线程池的有效线程中,如果失败,执行拒绝策略
    }
}

5)、addWorker(Runnable firstTask, boolean core),ThreadPoolExecutor中方法,添加有效线程;

private boolean addWorker(Runnable firstTask, boolean core) {
        retry://retry后面跟循环,标记这个循环的位置。break后面加retry表示要跳出这个标记的循环,continue后面加retry表示跳过这个标记的循环的本次循环。
        for (;;) {
            int c = ctl.get();//获取线程池运行状态和有效线程数
            int rs = runStateOf(c);//获取线程池运行状态

            //不能添加有效线程的情况,直接返回false
            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;
                if (compareAndIncrementWorkerCount(c))//CAS操作,使得有效线程数+1
                    break retry;//CAS操作成功,跳出retry循环
                c = ctl.get();  // 再次获取线程池运行状态和有效线程数
                if (runStateOf(c) != rs)//线程池运行状态改变
                    continue retry;//跳过本次循环,继续retry标记的循环
            }
        }
        
        boolean workerStarted = false;//新线程成功启动标识
        boolean workerAdded = false;//新线程添加到workers中的标识
        Worker w = null;
        try {
            final ReentrantLock mainLock = this.mainLock;//可重入锁
            w = new Worker(firstTask);//将firstTask封装成Worker对象
            final Thread t = w.thread;//w对应的线程
            if (t != null) {
                mainLock.lock();
                try {
                    int c = ctl.get();
                    int rs = runStateOf(c);
                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        if (t.isAlive()) //检查线程t是否已经启动
                            throw new IllegalThreadStateException();
                        workers.add(w);//w添加到workers中
                        int s = workers.size();//workers的大小
                        if (s > largestPoolSize)//如果s大于largestPoolSize,则需要将s赋值给largestPoolSize
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    t.start();
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);//将线程添加到workers中失败,需要回滚
        }
        return workerStarted;
    }

6)、Worker类,继承AQS,实现Runnable,提供了线程中断机制;

private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable
    {
        private static final long serialVersionUID = 6138294804551838833L;

        //执行任务的线程
        final Thread thread;
        //需要执行的任务,可为空
        Runnable firstTask;
        //执行的任务书
        volatile long completedTasks;

        //构造方法
        Worker(Runnable firstTask) {
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);//将worker对象传入到线程中,线程启动后,会执行下面的run方法
        }

        public void run() {
            runWorker(this);
        }

        //锁的状态,1:加锁状态;0:未加锁状态
        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) {
                }
            }
        }
    }

7)、runWorker(Worker w),ThreadPoolExecutor中方法,Worder中run方法的实际业务;

    final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();//获取当前线程
        Runnable task = w.firstTask;//获取Worker对象中的任务
        w.firstTask = null;
        w.unlock(); // 允许中断
        boolean completedAbruptly = true;
        try {
            //任务不为空或者从任务队列中获取的任务不为空,则进入while循环
            while (task != null || (task = getTask()) != null) {
                w.lock();
                //检查当前线程是否需要中断
                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);//类似beforeExecute
                    }
                } finally {
                    task = null;
                    w.completedTasks++;
                    w.unlock();
                }
            }
            completedAbruptly = false;
        } finally {
            processWorkerExit(w, completedAbruptly);//处理worker退出的流程
        }
    }

8)、getTask(),ThreadPoolExecutor中方法,从任务队列中获取任务。

private Runnable getTask() {
        boolean timedOut = false; // Did the last poll() time out?

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

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {// 1)、当前线程池的运行状态是STOP、TIDYING、TERMINATED中的一个;2)、当前线程池的运行状态是SHUTDOWN,任务队列已空;
                decrementWorkerCount();//有效线程数减1
                return null;
            }

            boolean timed;      // Are workers subject to culling?

            for (;;) {
                int wc = workerCountOf(c);
                timed = allowCoreThreadTimeOut || wc > corePoolSize;//核心线程设置了存活时间或者有效线程数大于核心线程数(存在非核心线程)

                if (wc <= maximumPoolSize && ! (timedOut && timed))
                    break;
                if (compareAndDecrementWorkerCount(c))
                    return null;
                c = ctl.get();  // Re-read ctl
                if (runStateOf(c) != rs)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }

            try {
            //根据timed的值,对r进行赋值。timed为true,调用workQueue.poll(),如果在限定时间内没有取到任务,执行timedOut = true;timed为false,调用workQueue.take(),如果没有立即拿到任务,线程会被阻塞,直到从任务队列拿到任务
                Runnable r = timed ?
                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                    workQueue.take();
                if (r != null)
                    return r;
                timedOut = true;
            } catch (InterruptedException retry) {
                timedOut = false;
            }
        }
    }

 

ScheduledThreadPoolExecutor中execute方法

newScheduledThreadPool、newSingleThreadScheduledExecutor的execute方法则是在ScheduledThreadPoolExecutor中。

直接从execute方法开始看

1)、execute(Runnable command),ScheduledThreadPoolExecutor中方法,调用的是schedule方法,延时时间为0;

    public void execute(Runnable command) {
        schedule(command, 0, TimeUnit.NANOSECONDS);
    }

2)、schedule(Runnable command, long delay, TimeUnit unit),ScheduledThreadPoolExecutor中方法,延时执行任务;

  public ScheduledFuture<?> schedule(Runnable command,
                                       long delay,
                                       TimeUnit unit) {
        if (command == null || unit == null)
            throw new NullPointerException();
        //将提交的任务转换成ScheduledFutureTask
        RunnableScheduledFuture<?> t = decorateTask(command,
            new ScheduledFutureTask<Void>(command, null,
                                          triggerTime(delay, unit)));
        delayedExecute(t);//延时执行任务
        return t;
    }

3)、delayedExecute(RunnableScheduledFuture<?> task),ScheduledThreadPoolExecutor中方法,延时执行任务的具体实现;

  private void delayedExecute(RunnableScheduledFuture<?> task) {
        if (isShutdown())//当前线程池是否处于SHUTDOWN状态
            reject(task);执行拒绝策略
        else {
            super.getQueue().add(task);//任务加入到任务队列中
            if (isShutdown() &&
                !canRunInCurrentRunState(task.isPeriodic()) &&
                remove(task))//线程池是否关闭&&是否可以执行定期任务&&移除任务
                task.cancel(false);//以不可中断方式执行完成执行中的调度任务
            else
                ensurePrestart();//即使核心线程数为0,也要确保至少一个线程启动
        }
    }

4)、remove(Runnable task),ThreadPoolExecutor中方法,移除任务;

    public boolean remove(Runnable task) {
        boolean removed = workQueue.remove(task);//移除任务
        tryTerminate(); //尝试终止线程池
        return removed;
    }

5)、tryTerminate(),ThreadPoolExecutor中方法,尝试终止线程池;

final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            //线程池处于RUNNING状态(不能中断) || 线程池处于TIDYING/TERMINATED状态(不需要中断)||线程池处于SHUTDOWN状态,任务队列不为空(不能中断)
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
                return;
            if (workerCountOf(c) != 0) { //可以中断情况,但是有效线程数不为0
                interruptIdleWorkers(ONLY_ONE);//ONLY_ONE为true,中断有效线程中的一个
                return;
            }

            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {//将线程池设置成TIDYING状态
                    try {
                        terminated();//线程池终止时调用方法
                    } finally {
                        ctl.set(ctlOf(TERMINATED, 0));//线程池状态设置成TERMINATED
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

 6)、interruptIdleWorkers(boolean onlyOne),ThreadPoolExecutor中方法,中断可能正在等待任务(未被锁定)的线程,以便它们可以检查终止或配置更改;

   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();
        }
    }

7)、 ensurePrestart(),ThreadPoolExecutor中方法,确保存在一个线程存在。

    void ensurePrestart() {
        int wc = workerCountOf(ctl.get());//获取有效线程数
        //添加一个任务为空的线程,执行时都会从任务队列中获取任务
        if (wc < corePoolSize)//有效线程数小于核心线程数
            addWorker(null, true);//有效线程最大值为核心线程数
        else if (wc == 0)//有效线程数为0
            addWorker(null, false);//有效线程最大值为线程池中允许存在的最大线程数
    }

以上就是线程池的execute方法的解析。

 

 

如果有写的不对的地方,请大家多多批评指正,非常感谢!

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值