一些关键属性字段:
1、runState,记录该线程池的状态:
volatile int runState;
1)RUNNING(0):接受新的task,并执行queue中的task
2)SHUTDOWN(1):不接受新的task,执行完当前任务,并执行queue中的task。调用shutdown()方法,线程池为该状态
3)STOP(2):不接受新的task,不执行queue中task,并且中断(interrupt)当前方法。调用shutdownNow()
4)TERMINATED(3):不接受新的task,不执行queue中task,全部的线程都停止。
2、workQueue,存放task队列和与线程交互。有三种BlockingQueue,ArrayBlockingQueue,LinkedBlockingQueue,PriorityBlockingQueue
BlockingQueue<Runnable> workQueue;3、修改poolSize, corePoolSize, maximumPoolSize, runState, and workers set用到的锁
private final ReentrantLock mainLock = new ReentrantLock();4、存储工作线程的set
private final HashSet<Worker> workers = new HashSet<Worker>();5、idle线程等待时间,大于这个时间线程会终止。注意,使用这个参数时,只有当线程数大于corePoolSize,并且allowCoreThreadTimeOut为false时,超出corePoolSize的线程才会使用这个参数作为终止等待时间。
private volatile long keepAliveTime;
6、默认为false,为false时,core线程(线程数小于或等于corePoolsize)永远存活在idle状态,如果为true,core线程在idle状态会存活keepAliveTime时间。
private volatile boolean allowCoreThreadTimeOut;7、core线程数(核心线程数),修改时需要mainLock获取锁。没有任务执行时,线程池的大小,只有当工作队列满了,才会创建超过corePoolSize的数量线程。线程池运行初期,并不会立即创建线程,只有当线程提交时才会创建线程,除非设置了prestartAllCoreThreads
private volatile int corePoolSize;8、最大线程数,修改时需要mainLock获取锁。线程池中允许最大线程数。
private volatile int maximumPoolSize;9、当前线程池线程实际个数,修改时需要mainLock获取锁。
private volatile int poolSize;10、当前运行线程达到最大maximumPoolSize,而且队列已满或者当前线程池blocked,再来的新task就会被拒绝,并执行handler中的方法
private volatile RejectedExecutionHandler handler;11、线程工厂,创建线程的工厂类,如果要设置线程的名字、处理线程抛出异常时候,要设置线程工厂
private volatile ThreadFactory threadFactory;重要方法 1、当一个task提交到线程池的时候,如果当前线程池(poolsize)的数量小于corePoolSize,则会新创建一个线程来运行当前task,其他线程仍然处于idle状态;如果当前线程数大于corePoolSize,且小于maximumPoolSize,只有当阻塞队列满了的时候,才会创建一个新的线程来运行提交task。
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); //如果当前线程池(poolsize)的数量小于corePoolSize,则会新创建一个线程来运行当前task if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) { //如果当前线程数大于corePoolSize,task进入队列。 if (runState == RUNNING && workQueue.offer(command)) { //double check一下,当进入队列的之后,线程池停止,则把任务移除队列 if (runState != RUNNING || poolSize == 0) ensureQueuedTaskHandled(command); } //如果当前线程数大于corePoolSize,且小于maximumPoolSize,只有当阻塞队列满了的时 候,才会创建一个新的线程来运行提交task。 else if (!addIfUnderMaximumPoolSize(command)) reject(command); // is shutdown or saturated } } private boolean addIfUnderCorePoolSize(Runnable firstTask) { Thread t = null; ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { if (this.poolSize < this.corePoolSize) if (this.runState == 0) t = addThread(firstTask);//如果当前线程池(poolsize)的数量小于corePoolSize,增加线程数量 } finally { mainLock.unlock(); } if (t == null) return false; t.start(); return true; } private Thread addThread(Runnable firstTask) { Worker w = new Worker(firstTask);//创建工作线程 Thread t = this.threadFactory.newThread(w); //使用ThreadFactory创建新的线程 if (t != null) { w.thread = t; this.workers.add(w); int nt = ++this.poolSize; if (nt > this.largestPoolSize) this.largestPoolSize = nt; } return t; }
2、工作线程类:
内部的线程运行锁,当前线程运行时,不可以中断,当在不运行的时候,才可中断
private final ReentrantLock runLock = new ReentrantLock();
当前工作线程被创建并运行的第一个task,可以为null
private Runnable firstTask;
当前线程完成的任务数
volatile long completedTasks;
当前工作的线程,在线程创建时会被赋值
Thread thread;
中断线程的方法
/** * Interrupts thread if not running a task. */ void interruptIfIdle() { //获取当前线程中的锁,如果可以获得改锁,说明该线程处于idle状态 final ReentrantLock runLock = this.runLock; if (runLock.tryLock()) { try { if (thread != Thread.currentThread()) thread.interrupt(); } finally { runLock.unlock(); } } } /** * Interrupts thread even if running a task. */ void interruptNow() { thread.interrupt(); }
构造函数
Worker(Runnable firstTask) { this.firstTask = firstTask; }
线程工作类:
public void run() { try { Runnable task = firstTask; firstTask = null; //如果任务为空,则从队列中获取任务 while (task != null || (task = getTask()) != null) { //执行任务方法 runTask(task); task = null; } } finally { workerDone(this); } }
3、执行任务方法:
private void runTask(Runnable task) { //执行任务时,获取work内运行锁 final ReentrantLock runLock = this.runLock; runLock.lock(); try { //检查两次runState的状态,如果处于RUNNING或者SHUTDOWN状态,继续执行,如果检查当前线程被interrupt,则double check runState状态,如果处于STOP以上状态,则中断线程(用户调用shutdownNow方法) if (runState < STOP && Thread.interrupted() && runState >= STOP) thread.interrupt(); boolean ran = false; beforeExecute(thread, task); try { //执行任务方法 task.run(); ran = true; afterExecute(task, null); ++completedTasks; } catch (RuntimeException ex) { if (!ran) afterExecute(task, ex); throw ex; } } finally { runLock.unlock(); } }
4、获取任务的方法
Runnable getTask() { for (;;) { try { int state = runState; //STOP,TERMINATED不再执行队列中的方法 if (state > SHUTDOWN) return null; Runnable r; if (state == SHUTDOWN) // Help drain queue r = workQueue.poll(); //SHUTDOWN执行队列中的方法 else if (poolSize > corePoolSize || allowCoreThreadTimeOut) //如果poolSize大于corePoolSize,当前线程等待多久获取不到task,则退出 //如果是allowCoreThreadTimeOut为true,表示core线程也可以等待一段时间,如果获取不到task,则退出 r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS); else r = workQueue.take(); if (r != null) return r; //工作线程work退出 if (workerCanExit()) { //如果当前线程池为SHUTDOWN以上状态,则中断所有idle的workers if (runState >= SHUTDOWN) // Wake up others interruptIdleWorkers(); return null; } // Else retry } catch (InterruptedException ie) { // On interruption, re-check runState } } }
5、关闭线程池方法
public void shutdown() { SecurityManager security = System.getSecurityManager(); if (security != null) //检查当前调用者是否有关闭线程池的权限 security.checkPermission(shutdownPerm); final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { if (security != null) { // Check if caller can modify our threads //检查调用者是否有修改每个线程的权限 for (Worker w : workers) security.checkAccess(w.thread); } //修改当前线程池状态为shutdown状态 int state = runState; if (state < SHUTDOWN) runState = SHUTDOWN; //中断当前线程池中处于idle状态线程 try { for (Worker w : workers) { w.interruptIfIdle(); } } catch (SecurityException se) { // Try to back out runState = state; // tryTerminate() here would be a no-op throw se; } //尝试设置为TERMINATE状态 tryTerminate(); // Terminate now if pool and queue empty } finally { mainLock.unlock(); } }
6、立即关闭线程池的方法
public List<Runnable> shutdownNow() {//类似于shutdown /* * shutdownNow differs from shutdown only in that * 1. runState is set to STOP, 将runState设置成STOP状态 * 2. all worker threads are interrupted, not just the idle ones, and 每个线程调用interrupted方法中断线程 * 3. the queue is drained and returned. 把等待队列中的task返回 */