ThreadPoolExecutor 源码分析
ThreadPoolExecutor // runState is stored in the high-order bits //能提交新的任务,并且也能处理阻塞队列中的任务 private static final int RUNNING = -1 << COUNT_BITS; //关闭状态,不再接收新提交的任务,但却可以继续处理阻塞队列中的任务 private static final int SHUTDOWN = 0 << COUNT_BITS; //不接受新任务,也不处理阻塞队列中的任务,会中断正在处理任务的线程 private static final int STOP = 1 << COUNT_BITS; //所有任务已经终止,workerCount(有效线程)为0 private static final int TIDYING = 2 << COUNT_BITS; //在terminated方法执行完成后进入改状态 private static final int TERMINATED = 3 << COUNT_BITS; 核心方法 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();//ctl 高三位 记录线程状态 后29位记录线程数 //计算当前线程数是否小于核心线程数,如果小于直接创建线程去执行 if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } //如果当前线程数正在运行并且阻塞队列未满 //执行阻塞队列的头结点任务(FIFO) if (isRunning(c) && workQueue.offer(command)) { //判断当前的线程状态如果不在运行,remove掉任务,拒绝任务的执行 int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); //如果当前有效线程数位0 ,不会把新的任务添加进去 else if (workerCountOf(recheck) == 0) addWorker(null, false); } //如果当前线程数大于核心线程数队列也满了,但是最大线程数没满尝试创建新的线程去执行,如果创建不了,就拒绝任务执行 else if (!addWorker(command, false)) reject(command); } private static int workerCountOf(int c) { return c & CAPACITY; } /** * Checks if a new worker can be added with respect to current * pool state and the given bound (either core or maximum). If so, * the worker count is adjusted accordingly, and, if possible, a * new worker is created and started, running firstTask as its * first task. This method returns false if the pool is stopped or * eligible to shut down. It also returns false if the thread * factory fails to create a thread when asked. If the thread * creation fails, either due to the thread factory returning * null, or due to an exception (typically OutOfMemoryError in * Thread.start()), we roll back cleanly. * * @param firstTask the task the new thread should run first (or * null if none). Workers are created with an initial first task * (in method execute()) to bypass queuing when there are fewer * than corePoolSize threads (in which case we always start one), * or when the queue is full (in which case we must bypass queue). * Initially idle threads are usually created via * prestartCoreThread or to replace other dying workers. * * @param core if true use corePoolSize as bound, else * maximumPoolSize. (A boolean indicator is used here rather than a * value to ensure reads of fresh values after checking other pool * state). * @return true if successful */ private boolean addWorker(Runnable firstTask, boolean core) { retry: for (;;) { int c = ctl.get(); int rs = runStateOf(c);//获取当前的状态 // Check if queue empty only if necessary. //如果当前状态是不是正在运行状态 并且提交的任务不为空或者阻塞队列为空 直接返回false,也就是创建新线程失败了,此时可能是刚开始执行时也可能是核心线程满了队列也满了,但最大线程数没满,所以这里判断阻塞队列为非空,如果为非空还需要继续执行队列里面的任务 if (rs >= SHUTDOWN && ! (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty())) return false; //自旋操作 //判断条件是 不能大于核心线程数或者最大线程数 根据core来判断 core在executor中传入 //此时是工作线程+1操作可能多个线程一起在操作这里用cas来控制这个操作,成功就退出循环,否则就自旋,直到操作成功 for (;;) { int wc = workerCountOf(c); if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize)) return false; 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 w = null; try { //创建工作线程 w = new Worker(firstTask); 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. int rs = runStateOf(ctl.get()); //判断线程池状态 //满足后 就执行了 if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) { if (t.isAlive()) // precheck that t is startable throw new IllegalThreadStateException(); 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; } 任务分发 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时还会处理阻塞队列中的任务,所以只有die或者terminal的或者祖册队列中任务时才会返回null if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) { decrementWorkerCount(); return null; } int wc = workerCountOf(c);//获取工作线程数 // Are workers subject to culling? //如果任务执行超时了 或者已经超过了最大线程数 更新工作线程数返回null也就是没获取到任务 boolean timed = allowCoreThreadTimeOut || wc > corePoolSize; if ((wc > maximumPoolSize || (timed && timedOut)) && (wc > 1 || workQueue.isEmpty())) { if (compareAndDecrementWorkerCount(c)) return null; continue; } try { //超时就移除否则就取头节点 如果没有节点的话 就会阻塞在这里 //这里的timed值的是上面设置的允许超时或者超过核心线程数,为什么超过核心线程数就是timed了?未超过核心线程数是直接创建线程执行的,只有超过核心线程了才会往blockQuene中添加,如果timed了就移除这个,否则就取头节点 如果blockQuene中没有节点,就会阻塞在这里 Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) ://超过时间获取到移除的元素也就是队列中没有元素 workQueue.take(); if (r != null) return r; timedOut = true; } catch (InterruptedException retry) { timedOut = false; } } }