核心的几个线程池,newFixedThreadPool(), newSingleThreadExecutor()和newCachedThreadPool()方法,内部实现都是使用了ThreadPoolExecutor()实现。
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
ThreadPoolExecutor最重要的构造函数:
public ThreadPoolExecutor( int corePoolSize, //指定了线程池中线程数量 int maximumPoolSize, // 线程池中的最大线程数量 long keepAliveTime, // 当线程数量超过corePoolSize时,对于空闲线程的存活时间,即多余空闲线程多久会被销毁 TimeUnit unit,//keepAliveTime的单位 BlockingQueue<Runnable> workQueue,// 任务队列,被提交但尚未被执行的任务 ThreadFactory threadFactory, //线程工厂,用于创建线程,一般用默认的即可 RejectedExecutionHandler handler // 拒绝策略。当任务太多来不及处理,如何拒绝任务 ) |
workQueue是一个BlockingQueue接口的对象,仅用于存放Runnable对象;
所有BlockingQueue 都可用于传输和保持提交的任务。可以使用此队列与池大小进行交互:
如果运行的线程少于 corePoolSize,则 Executor始终首选添加新的线程,而不进行排队。(如果当前运行的线程小于corePoolSize,则任务根本不会存放,添加到queue中,而是直接抄家伙(thread)开始运行)
如果运行的线程等于或多于 corePoolSize,则 Executor始终首选将请求加入队列,而不添加新的线程。
如果无法将请求加入队列,则创建新的线程,除非创建此线程超出 maximumPoolSize,在这种情况下,任务将被拒绝
根据功能分类,可使用以下几种BlockingQueue:
|
ThreadPoolExecutor核心调度代码
在分析该类的execute方法前,先看这几个常量的值和一些方法的作用
1 /* 2 * ctl的默认值为-536870912, 3 * 作用是将该值传入workerCountOf(int c)的参数c中, 4 * 则可以返回正在工作的线程数量 5 * 每当有一个线程加入工作,该值会加1 6 */ 7 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); 8 private static final int COUNT_BITS = Integer.SIZE - 3; //32-3=29 9 private static final int CAPACITY = (1 << COUNT_BITS) - 1;//536870911 10 0001 1111 1111 1111 1111 1111 1111 1111 11 // runState is stored in the high-order bits,其中running<shutdown<stop<tidying<terminated 12 private static final int RUNNING = -1 << COUNT_BITS;// -536870912 1010 0000 0000 0000 0000 0000 0000 0000 13 private static final int SHUTDOWN = 0 << COUNT_BITS;//0 0000 0000 0000 0000 0000 0000 0000 0000 14 private static final int STOP = 1 << COUNT_BITS;//536870912 0010 0000 0000 0000 0000 0000 0000 0000 15 private static final int TIDYING = 2 << COUNT_BITS;//1073741824 0100 0000 0000 0000 0000 0000 0000 0000 16 private static final int TERMINATED = 3 << COUNT_BITS;//1610612736 0110 0000 0000 0000 0000 0000 0000 0000 17 18 // Packing and unpacking ctl 19 private static int runStateOf(int c) { return c & ~CAPACITY; }//当c<0时该方法返回的值为-536870912,否则为0 20 private static int workerCountOf(int c) { return c & CAPACITY; }//获取工作线程数 21 private static int ctlOf(int rs, int wc) { return rs | wc; }//-536870912 |
execute
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); } |
addWorker
1 private boolean addWorker(Runnable firstTask, boolean core) { 2 //外部循环 3 retry: 4 for (;;) { 5 int c = ctl.get();//获取当前工作线程数量,数量为{c-(-536870912)} 6 7 int rs = runStateOf(c);//若c>=0时,该值才为0,否则该值一直为-536870912 8 9 10 /* 11 *由上面的一些线程池状态常量值可知,running<shutdown<stop<tidying<terminated 12 *若rs>=shutdown,则表明线程池处于stop、tidying、terminated三种状态的一种 13 *若rs>=shutdown成立,则进行后面判断, 14 *1、线程池处于shutdown状态 15 * 1.1、firstTask不为null,则返回false,也即是线程池已经处于shutdown状态,还要添加新的线程,被直接驳回(拒绝) 16 * 1.2、firstTask为null 17 * 1.2.1、此时意味着线程池状态为shutdown状态,且first为null,若阻塞队列为空,则返回false 18 *2、线程处于大于shutdown的状态,则直接返回false 19 */ 20 if (rs >= SHUTDOWN && 21 ! (rs == SHUTDOWN && 22 firstTask == null && 23 ! workQueue.isEmpty())) 24 return false; 25 /* 26 *进入内循环以下两种情况会跳出该内循环,否则一直会循环 27 *1、当工作线程数量超过一定阈值,会直接返回false 28 *2、添加工作线程成功,即ctl的值进行了加一 29 */ 30 for (;;) { 31 int wc = workerCountOf(c);//获取工作线程的数量 32 //当线程数量>=536870911或者>=corePoolSize或maximumPoolSize的时候,则返回false 33 if (wc >= CAPACITY || 34 wc >= (core ? corePoolSize : maximumPoolSize)) 35 return false; 36 if (compareAndIncrementWorkerCount(c))//使用unsafe的cas操作对ctl.get()的值进行加一 37 break retry;//跳出这个外循环 38 c = ctl.get(); // Re-read ctl 39 if (runStateOf(c) != rs)//当此时的线程池状态和之前的状态不等时 40 continue retry;//继续内循环 41 } 42 } 43 //若进行到了此步操作,则表明工作线程数量加了1 44 boolean workerStarted = false; 45 boolean workerAdded = false; 46 Worker w = null; 47 try { 48 w = new Worker(firstTask); 49 final Thread t = w.thread;//该w.thread为worker内部新创建的thread 50 if (t != null) { 51 final ReentrantLock mainLock = this.mainLock; 52 mainLock.lock();//开启锁 53 try { 54 //获取锁后,再次获取线程池的状态 55 int rs = runStateOf(ctl.get()); 56 /* 57 *1、当线程池的状态处于shutdown以上状态,则直接释放锁,不启动线程,且执行addWorkerFailed方法 58 执行该方法的作用是使工作线程数量-1 59 */ 60 if (rs < SHUTDOWN || 61 (rs == SHUTDOWN && firstTask == null)) { 62 if (t.isAlive()) // 创建的线程处于活跃状态,即被启动了,抛出异常 63 throw new IllegalThreadStateException(); 64 workers.add(w);//workers是一个set集合 65 int s = workers.size(); 66 if (s > largestPoolSize)//largestPoolSize默认为0,作用是记录set集合中的线程数量 67 largestPoolSize = s; 68 workerAdded = true;//改变该值,为了启动线程,且返回一个addWorker执行成功的状态 69 } 70 } finally { 71 mainLock.unlock();//释放锁 72 } 73 if (workerAdded) { 74 t.start(); 75 workerStarted = true; 76 } 77 } 78 } finally { 79 if (! workerStarted) 80 addWorkerFailed(w); 81 } 82 return workerStarted; 83 } |