1、线程池的处理流程(execute方法) 当向线程池提交一个任务后,其经历的流程如下: 1)、如果当前线程数小于核心线程数(corePoolSize),则创建新线程来执行该任务; 2)、如果当前线程数不小于,即等于或大于核心线程数(corePoolSize),则将任务添加到阻塞队列(BlockingQueue)中; 3)、如果阻塞队列中的任务已满,且此时线程数小于最大线程数(maximumPoolSize)时,则创建新线程来执行该任务; 4)、执行对应的任务策略,一般是拒绝任务,抛出异常。 2、任务策略: 1)、抛出异常 ThreadPoolExecutor.AbortPolicy() 2)、丢弃当前的任务 ThreadPoolExecutor.DiscardPolicy() 3)、丢弃老的任务 ThreadPoolExecutor.DiscardOldestPolicy() 4)、重试添加当前的任务 ThreadPoolExecutor.CallerRunsPolicy() 3、线程池源码分析 1)、若干变量 //将工作线程数和线程池状态放在一个int类型变量中存储而设置的一个原子类型的变量 //故在ctl中,低29位是用于表示工作线程数,高位用于表示线程池状态,如RUNNING、SHUTDOWN等。 //故一个线程池中最多有工作线程的个数为(2^29) - 1 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); //低29位 private static final int COUNT_BITS = Integer.SIZE - 3; //线程池中最大的工作线程数 private static final int CAPACITY = (1 << COUNT_BITS) - 1; // runState is stored in the high-order bits //线程池状态,用高3位表示 private static final int RUNNING = -1 << COUNT_BITS; 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; // Packing and unpacking ctl //获取当前线程池的状态 private static int runStateOf(int c) { return c & ~CAPACITY; } //获取当前线程池中的工作线程数 private static int workerCountOf(int c) { return c & CAPACITY; } //组合当前线程池状态和工作线程数为一个int类型的变量 private static int ctlOf(int rs, int wc) { return rs | wc; } 2)、execute()方法 public void execute(Runnable command) { //当提交的任务为null时,则抛出空指针异常 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(); if (! isRunning(recheck) && remove(command)) //当前线程池不是运行状态,且删除成功时,使用任务策略 reject(command); else if (workerCountOf(recheck) == 0) //当前工作线程数为0时,直接添加空任务 addWorker(null, false); } else if (!addWorker(command, false)) //阻塞队列已满且当前工作线程数小于最大线程数时,则直接创建线程,执行任务 //若还失败,则直接使用任务策略 reject(command); } private boolean addWorker(Runnable firstTask, boolean core) { retry: for (;;) { int c = ctl.get(); //获取当前线程池的状态 int rs = runStateOf(c); //检测当前线程池是否处于关闭状态 // Check if queue empty only if necessary. 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增加一个工作线程 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 { final ReentrantLock mainLock = this.mainLock; //新建一个工作线程 w = new Worker(firstTask); final Thread t = w.thread; if (t != null) { mainLock.lock(); //加锁 try { // Recheck while holding lock. // Back out on ThreadFactory failure or if // shut down before lock acquired. int c = ctl.get(); int rs = runStateOf(c); if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) { if (t.isAlive()) // precheck that t is startable throw new IllegalThreadStateException(); //将工作线程添加到线程集合Set中 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(Runnable firstTask) { setState(-1); // inhibit interrupts until runWorker this.firstTask = firstTask; this.thread = getThreadFactory().newThread(this); } //线程执行体 /** Delegates main run loop to outer runWorker */ public void run() { //调用父类的runWorker方法 runWorker(this); } final void runWorker(Worker w) { Thread wt = Thread.currentThread(); Runnable task = w.firstTask; w.firstTask = null; w.unlock(); // allow interrupts boolean completedAbruptly = true; try { //不断的从任务队列中获取任务,并执行 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 { //任务执行前的执行方法 beforeExecute(wt, task); Throwable thrown = null; try { //执行任务 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 = null; w.completedTasks++; w.unlock(); } } completedAbruptly = false; } finally { processWorkerExit(w, completedAbruptly); } } //调用该方法后,该线程池不会再接受新任务,当已经存在的任务执行完毕后,线程池就会关闭 void shutdown() //调用该方法后,该线程池会尝试关闭现有的线程,直到所有的线程都关闭,线程池就会关闭 List<Runnable> shutdownNow() 4、常用的线程池 1)、固定大小线程的线程池 newFixedThreadPool 2)、单一线程的线程池,当线程发生异常结束时,则会另外创建一个新的线程,以保持线程池自始至终只有一个线程 newSingleThreadExecutor 3)、无限制线程数的线程池,当空闲线程超过空闲时间时(默认1分钟),线程会被回收 newCachedThreadPool 5、阻塞队列 //往队列中添加元素,成功返回true,失败抛出异常 boolean add(E e) //往队列中添加元素,成功返回true,失败返回false boolean offer(E e) //往队列中添加元素,在指定的时间内若是添加不了,则返回false,否则返回true boolean offer(E e, long timeout, TimeUnit unit) //有阻塞的添加元素,即肯定能将元素添加到队列中,但是可能一直被阻塞 void put(E e) throws InterruptedException //获取队列中的首元素,没有返回null E poll() //获取队列中的首元素,在指定的时间内若是获取不到,则返回null E poll(long timeout, TimeUnit unit) //获取队列中的首元素,当队列中没有元素时,则一直阻塞,直到有元素时,才返回首元素 E take()