Java线程池

通过Executors创建线程池的时候调用newFixedThreadPool方法,继承的大概结构如下:

创建完成之后,线程池的结构如下:

在创建完线程池之后就可以调用execute方法来执行给定的Runnable了,具体的代码如下:

 1     public void execute(Runnable command) {
 2         if (command == null)
 3             throw new NullPointerException();
 4         if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
 5             if (runState == RUNNING && workQueue.offer(command)) {
 6                 if (runState != RUNNING || poolSize == 0)
 7                     ensureQueuedTaskHandled(command);
 8             }
 9             else if (!addIfUnderMaximumPoolSize(command))
10                 reject(command);
11         }
12     }

执行的流程还是很简单的,大致如下:

看到这里,把任务加入到了任务队列里面了,那么怎么运行这个方法呢?

在前面用C也些过一个线程池,同样是不断地循环去检查任务队列中是否有任务需要执行,有?从中取出来执行,这样该线程执行的代码段就改变了,变成设置的方法。如果发现任务队列中没有了多余的任务了,那么对应Worker的run方法中while循环也就该结束了,这样这个线程就消失了。run方法的代码如下:

 1         public void run() {
 2             try {
 3                 Runnable task = firstTask;
 4                 firstTask = null;
 5                 while (task != null || (task = getTask()) != null) {
 6                     runTask(task);
 7                     task = null;
 8                 }
 9             } finally {
10                 workerDone(this);
11             }
12         }

 大致的执行流程如下:

上面这个流程中最关键的是runTask,但是第一句就让人不明白了,runState<STOP和runState>=STOP不是矛盾的么?首先看一下线程池的各个状态的含义:

  • RUNNING=0,还可以接受新的任务;
  • SHUTDOWN=1,不会再接受新任务,但是会把现有的任务执行完;
  • STOP=2,所有的任务都完成了并处在中断状态;
  • TERMINATED=3,所有的任务完成并且线程也都推出了;

如果runState<STOP成立,说明还有线程正在运行,也就是该条件为ture,然后就会执行Thread.interrupted()方法,该方法检查当前的线程是否正在中断状态,如果是中断状态的话返回true,否则返回false,如果runState>=STOP的话说明处于中断状态时正常的,让它继续处于中断状态,否则该函数清除掉了线程的中断状态。

beforeExecute预先执行以确保Runnable在Thread中。

然后task.run()方法可以像调用普通方法那样使得给定的代码得以执行。

afterExecute在方法运行没有发生异常或错误的时候才会执行,貌似是记录了一下运行时间的日志。

在一个Worker发现任务队列中没有多余的任务来执行的时候,while循环也就结束了,这时候就会调用方法workerDone,在该方法中更新统计信息:

 1     void workerDone(Worker w) {
 2         final ReentrantLock mainLock = this.mainLock;
 3         mainLock.lock();
 4         try {
 5             completedTaskCount += w.completedTasks;
 6             workers.remove(w);
 7             if (--poolSize == 0)
 8                 tryTerminate();
 9         } finally {
10             mainLock.unlock();
11         }
12     }

 

上面是对最简单的线程池执行的流程。

-------------------------------------------

个人理解,欢迎拍砖。

posted @ 2012-04-10 17:04  GG大婶  阅读(2371)  评论(0编辑  收藏  举报