线程池的设计与原理解析(二)之---execute()方法

在使用线程池的时候,我们会使用到提交线程池的方法execute()。

 public void execute(Runnable command) {
    
    
  e.execute(command); 
  }

它的主要作用是提交执行任务,参数支持Runnable, execute()没有返回值,同时,它的任务里必须捕获异常。
execute()的工作主要流程如下图所示:
在这里插入图片描述

接下来就主要去看看这个execute()方法的源码含义
1.当传入一个 null的 Runnable的时候,会进行抛出异常

 if (command == null)
            throw new NullPointerException();

2.获取最新的ctl值

 int c = ctl.get();

3.进行了一次 workerCountOf© 和当前线程池核心数的比较,如果true,则可以提交此次线程数量,进行创建一个worker

 if (workerCountOf(c) < corePoolSize) {
    
    
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }

4.再往下走,表示addworker失败了,或者当前线程数量 > corePoolSize,进入到方法后,再次获取最新的数量

 if (isRunning(c) && workQueue.offer(command)) {
    
    
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }

5.最后都不满足条件的话,走到了最后一个条件,表明当前线程池是非Running状态

 else if (!addWorker(command, false))
            reject(command);

该方法的具体描述如下:

    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.
         */
        // c : 获取ctl最新值
        int c = ctl.get();
        // workerCountOf(c) 获取当前线程的数量 true: 表示当前线程数量 < 核心线程数量
        // 表示此次提交线程数量,直接创建一个新的 worker.
        if (workerCountOf(c) < corePoolSize) {
    
    
            // core == true 表示采用核心线程数量限制 false 表示采用 maximumPoolSize
            if (addWorker(command, true))
                // 创建成功后, 直接返回
                return;
            // 创建失败:
            // 1.存在并发现象
            // 2.当前线程池状态发生了改变 Running SHUTDOWN STOP TIDYING , 当线程池状态非Running 会失败
            // 3.
            c = ctl.get();
        }
        // 执行到这里的情况:
        // 1.当前线程数达到了 corePoolSize
        // 2. addWorker失败了
        if (isRunning(c) && workQueue.offer(command)) {
    
    

            // 再次获取ctl的最新值
            int recheck = ctl.get();

            // 条件一:  ! isRunning(recheck) 成立: 说明你提交到队列之后,线程池状态被外部修改了
            // 条件二:  remove(command); true: 提交之后,线程池中的线程还未被消费
            if (! isRunning(recheck) && remove(command))
                // 提交之后,线程池状态为非Running , 且任务出队成功,
                reject(command);

            //  workerCountOf(recheck)为 true:
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        // 执行到这里的情况
        // 1. offer() 失败
        // 2.当前线程池是非Running状态
        // 1.
        else if (!addWorker(command, false))
            reject(command);
    }

猜你喜欢

转载自blog.csdn.net/qq_35529931/article/details/119849251