JDK1.6中ThreadPoolExecutor源码阅读

一些关键属性字段:

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返回
*/
 
 

猜你喜欢

转载自chenghao666.iteye.com/blog/2377173