PooledExecutor 研究(第三方包,当时还没有用jdk5)

来源:互联网 发布:c语言char用法 编辑:程序博客网 时间:2024/06/06 03:00
 
以前记的笔记。

PooledExecutor基本以一个Channel以及一组Worker-Thread对组成。

Channel负责缓存目标请求(目标请求也是Runable接口的实现)以及“存”“取”。Channel是一个可以阻塞的Queue,他有4个方法。其中offer put 方法用来放入元素。polltake方法来获取数据。offer以及poll方法都是可以设定超时的阻塞方法。一旦超时则会将不再等待,并返回false。PooledExecutor主要使用0等待的的offer以及poll。

每一组W-T中的W(Runable的实现)成为目标请求的代理执行者,由T来负责真正启动执行。而执行的时候是由T来驱动其内部的W进行工作的。在一组W-T中Worker作为key、Thread作为value,形成字典形式。

工作基本流程基本如下:T中的W不断的从Channel中取请求(command也应该是Runable的实现)。如果没有请求,则等待或结束自己的运行。而每次放入请求时,都会检查(根据最大最小值的设定)是否需要多生成一个W-T对(PooledExecutor.addThread()方法);如果不需要则会直接放入Channel(Channel.offer方法);如果需要则会生成,并直接把自己给新生成的W。






元代码分析与注释:execute方法。

  1.  //将command放入线程池等待以及执行。
  2.   /**
  3.    * Arrange for the given command to be executed by a thread in this
  4.    * pool.  The method normally returns when the command has been
  5.    * handed off for (possibly later) execution.
  6.    **/
  7.   public void execute(Runnable command) throws InterruptedException {
  8.     for (;;) { 
  9.       synchronized(this) { 
  10.         if (!shutdown_) {
  11.           int size = poolSize_;
  12.           // 如果工作线程没有到达指定配置数则增加。
  13.           // addThread将会增加W-T对,并把command直接给他作为第一个command运行。
  14.           // Ensure minimum number of threads
  15.           if (size < minimumPoolSize_) {
  16.             addThread(command);
  17.             return;
  18.           }
  19.           
  20.           // 向Channel中存入command,并且不等待。
  21.           // 如果没有得到则,返回false。并且进入下一次循环(无限)或增加工作线程W-T。
  22.           // 
  23.           // Try to give to existing thread
  24.           if (handOff_.offer(command, 0)) { 
  25.             return;
  26.           }
  27.           
  28.           // 如果是工作线程不够,则增加W-T并执行command。
  29.           // If cannot handoff and still under maximum, create new thread
  30.           if (size < maximumPoolSize_) {
  31.             addThread(command);
  32.             return;
  33.           }
  34.         }
  35.       }
  36.       // 每次循环都执行BlockedExecutionHandler这个block Hook。
  37.       // 默认行为是由调用execute的线程自己来执行command。
  38.       // Cannot hand off and cannot create -- ask for help
  39.       if (getBlockedExecutionHandler().blockedAction(command)) {
  40.         return;
  41.       }
  42.     }//for
  43.   }


worker 的工作

  1.   /**
  2.    * Class defining the basic run loop for pooled threads.
  3.    **/
  4.   protected class Worker implements Runnable {
  5.     protected Runnable firstTask_;
  6.     protected Worker(Runnable firstTask) { firstTask_ = firstTask; }
  7.     public void run() {
  8.       try {
  9.         // 如果有默认的第一个command则执行它
  10.         Runnable task = firstTask_;
  11.         firstTask_ = null// enable GC
  12.         if (task != null) {
  13.           task.run();
  14.           task = null;
  15.         }
  16.         // 不断使用getTask()来获取 command (其实就是不断从Channel中取)。
  17.         // 执行command
  18.         while ( (task = getTask()) != null) {
  19.           task.run();
  20.           task = null;
  21.         }
  22.       }
  23.       catch (InterruptedException ex) { } // fall through
  24.       finally {
  25.         // 结束时 执行
  26.         workerDone(this);
  27.       }
  28.     }
  29.   }


getTask是比较奥妙的地方。


  1.   /** 
  2.    * Get a task from the handoff queue, or null if shutting down.
  3.    **/
  4.   protected Runnable getTask() throws InterruptedException {
  5.     long waitTime;
  6.     synchronized(this) {
  7.       if (poolSize_ > maximumPoolSize_) // Cause to die if too many threads
  8.         return null;
  9.       waitTime = (shutdown_)? 0 : keepAliveTime_;
  10.     }
  11.     if (waitTime >= 0
  12.       return (Runnable)(handOff_.poll(waitTime));
  13.     else 
  14.       return (Runnable)(handOff_.take());
  15.   }




原创粉丝点击