从源码分析:java中的线程池ThreadPoolExecutor

属性

// pool control state
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
// 读取Integer的位数,用前3位来表示当前线程池的状态
private static final int COUNT_BITS = Integer.SIZE - 3;
// 将后29位全部置1
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;
// 大于0的所有状态都是线程池不活跃的状态
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;

构造函数

输入的参数有,核心池的大小,最大池的大小,保活时间,保活时间的单位,阻塞队列的实例(用来暂时保存任务的工作队列),生成线程的工厂的实例,对于超时空闲线程的处理策略。

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();
        
        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();
            // 如果此时不处于运行状态,则尝试先删除command
            if (! isRunning(recheck) && remove(command))
                // 若无法正常删除,则执行拒绝策略
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        // 尝试往最大线程池中添加该任务
        else if (!addWorker(command, false))
            // 若添加失败,则执行拒绝策略
            reject(command);
    }
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.

翻译:

  1. 如果运行的corePoolSize线程少于核心,请尝试以给定命令作为第一个任务启动新线程。 添加Worker 原子检查运行状态和 workerCount 的调用,因此通过返回 false 来防止在不应添加线程时添加线程的误报。
  2. 如果任务可以成功排队,那么我们仍然需要仔细检查我们是否应该添加线程(因为现有线程自上次检查后已死)或池自进入此方法后关闭。因此,我们重新检查状态,如有必要,如果停止回滚排队,或者如果没有状态,则启动新线程。
  3. 如果无法对任务进行排队,则尝试添加新线程。 如果失败,我们知道我们被关闭或饱和,因此拒绝任务。

addWorker

private boolean addWorker(Runnable firstTask, boolean core) {
    // 因为内部有两层自旋的for循环,如果需要从内部的for循环跳出,则需要借助这个retry。
    retry:
    for (;;) {
        int c = ctl.get();
        int rs = runStateOf(c);

        // Check if queue empty only if necessary.
        // 获取当前线程池的状态,如果是STOP,TIDYING,TERMINATED状态的话,返回false
        // 如果是SHUTDOWN状态,则判断firstTask是否为null,且工作队列不为空,若是的话返回false
        if (rs >= SHUTDOWN &&
            ! (rs == SHUTDOWN &&
                firstTask == null &&
                ! workQueue.isEmpty()))
            return false;

        // 进入自旋
        for (;;) {
            int wc = workerCountOf(c);
            // 如果数量大于核心池(如果要加入的是核心池)或者最大池(要加入的是最大池),则返回false。
            if (wc >= CAPACITY ||
                wc >= (core ? corePoolSize : maximumPoolSize))
                return false;
            // 如果成功CAS修改了ctl的状态,则跳出retry
            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的指针
    Worker w = null;
    try {
        // 创建一个Worker的实例,并以传入的实例为其firstTask
        w = new Worker(firstTask);
        // 读取出w所创建的的线程
        final Thread t = w.thread;
        if (t != null) {
            // 加锁
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                // Recheck while holding lock.
                // Back out on ThreadFactory failure or if
                // shut down before lock acquired.
                // 持有锁后重新检查,若线程工厂错误或在获取锁之前shut down,则退出
                int rs = runStateOf(ctl.get());

                if (rs < SHUTDOWN ||
                    (rs == SHUTDOWN && firstTask == null)) {
                    if (t.isAlive()) // precheck that t is startable
                        throw new IllegalThreadStateException();
                    // workers是一个HashSet
                    workers.add(w);
                    int s = workers.size();
                    if (s > largestPoolSize)
                        largestPoolSize = s;
                    workerAdded = true;
                }
            } finally {
                mainLock.unlock();
            }
            if (workerAdded) {
                // 启动线程
                t.start();
                workerStarted = true;
            }
        }
    } finally {
        if (! workerStarted)
            addWorkerFailed(w);
    }
    return workerStarted;
}

Worker中的方法

内部类Worker是一个继承了AQS的内部类,并且实现了Runnable

构造方法

Worker(Runnable firstTask) {
    setState(-1); // inhibit interrupts until runWorker
    this.firstTask = firstTask;
    // 其内部持有的Thread线程实例,其实是将自己作为任务所创建的线程实例
    // 因此,这个线程的启动start(),其实就是启动这个worker实例的任务
    this.thread = getThreadFactory().newThread(this);
}
public void run() {
    // 调用外部类所写的runWorker方法,并将自己的实例this作为参数传入
    runWorker(this);
}
final void runWorker(Worker w) {
    // 获取当前线程
    Thread wt = Thread.currentThread();
    // 将worker实例w的firstTask作为task
    Runnable task = w.firstTask;
    // 将w的firstTask置空
    w.firstTask = null;

    w.unlock(); // allow interrupts
    boolean completedAbruptly = true;
    try {
        // 若task不为空或重新获取的任务不为空,则进入while循环
        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 {
                // 调用之前的操作,ThreadPoolExecutor中并没有写这个方法,但是如果是继承的子类可以重写这个方法
                beforeExecute(wt, task);
                // 用来保存所抛出的异常
                Throwable thrown = null;
                try {
                    // 将获得的task运行
                    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清空,意为除了第一次运行之外,之后的每一次都需要用getTask()来获取任务
                task = null;
                // 将w完成的任务的数量的计数器自增
                w.completedTasks++;
                w.unlock();
            }
        }
        // 如果正常完成,则会运行到这里(退出while之后),说明不是因为异常结束
        completedAbruptly = false;
    } finally {
        // 将workers退出workers,修改线程池的状态
        processWorkerExit(w, completedAbruptly);
    }
}
private Runnable getTask() {
    // 首先将超时的标志位timedOut置为false
    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.
        if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
            decrementWorkerCount();
            return null;
        }

        int wc = workerCountOf(c);

        // Are workers subject to culling?
        // 根据线程池实例的allowCoreThreadTimeOut属性来判断核心池中的线程是否超时关闭,对于最大池(线程数量超过核心池)中的线程,则确保使用超时关闭策略
        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

        if ((wc > maximumPoolSize || (timed && timedOut))
            && (wc > 1 || workQueue.isEmpty())) {
            if (compareAndDecrementWorkerCount(c))
                return null;
            continue;
        }

        try {
            // 通过阻塞队列的超时poll()方法来从阻塞队列中获取任务
            // 如果timed为false,则会一直阻塞在take()方法中
            Runnable r = timed ?
                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                workQueue.take();
            if (r != null)
                return r;
            timedOut = true;
        } catch (InterruptedException retry) {
            timedOut = false;
        }
    }
}
posted @ 2019-08-27 16:27  点点爱梦  阅读(148)  评论(0编辑  收藏  举报