美文网首页
Java线程池---execute函数解析

Java线程池---execute函数解析

作者: None_Ling | 来源:发表于2016-07-01 19:53 被阅读695次
      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))
                return;
            c = ctl.get();
        }
        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);
        }
        else if (!addWorker(command, false))
            reject(command);
    }
    

    execute方法中的步骤:

    1. 如果当前正在运行的线程数小于corePoolSize的话,那么尝试使用传入的command作为第一个任务启动一个新的线程执行。addWorker函数会原子性的检查runState以及workerCount防止不应该添加的新线程被添加。如果是假警报的话,那么addWorker函数就会返回false,表示添加新线程失败。
    2. 如果一个Task被成功的加入队列了,然后仍然需要重新check一次是否需要重新添加一个线程,因为有可能在上一次检查到这次检查之间,已经存在的线程已经死亡。或者,自从进入这个方法后,线程池已经被shut down。所以我们需要重新check状态,并且在必要的时候,如果处于stopped状态,需要重新回滚到队列中,或者如果没有的话,就需要重新启动一个线程。
    3. 如果不能把task加入到队列中,那么就会尝试去添加一个新的线程,如果它失败了,就知道是已经当前线程池是处于shut down或者处于饱和状态,那么就执行reject操作。

    函数执行流程:

    1. 通过workCountOf(c)拿到ctl中存储的当前线程总数,如果小于corePoolSize,那么就会走到addWorker方法中,如果成功创建了Worker的话,那么返回true,直接return,否则重新通过cas拿一次c
    2. 判断当前的线程池是否处于RUNNING状态,如果是,并且workQueue.offer加入队列成功话,那么那么就重新拿出来一次ctl,再判断如果加入队列之后,线程池如果不是处于RUNNING的状态,并且从队列中remove成功的话,那么就会执行reject操作
    3. 判断当前线程数是否为0,如果为0的话,那么就调用addWorker(null,false),否则如果非Running状态或者加入队列失败的话,那么就会调用addWorker(command,false)如果返回false,说明没有添加成功,就会执行reject操作。

    相关文章

      网友评论

          本文标题:Java线程池---execute函数解析

          本文链接:https://www.haomeiwen.com/subject/ezxqjttx.html