以前记的笔记。
PooledExecutor基本以一个Channel以及一组Worker-Thread对组成。
Channel负责缓存目标请求(目标请求也是Runable接口的实现)以及“存”“取”。Channel是一个可以阻塞的Queue,他有4个 方法。其中offer put 方法用来放入元素。poll take方法来获取数据。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方法。
- //将command放入线程池等待以及执行。
- /**
- * Arrange for the given command to be executed by a thread in this
- * pool. The method normally returns when the command has been
- * handed off for (possibly later) execution.
- **/
- public void execute(Runnable command) throws InterruptedException {
- for (;;) {
- synchronized(this) {
- if (!shutdown_) {
- int size = poolSize_;
- // 如果工作线程没有到达指定配置数则增加。
- // addThread将会增加W-T对,并把command直接给他作为第一个command运行。
- // Ensure minimum number of threads
- if (size < minimumPoolSize_) {
- addThread(command);
- return;
- }
- // 向Channel中存入command,并且不等待。
- // 如果没有得到则,返回false。并且进入下一次循环(无限)或增加工作线程W-T。
- //
- // Try to give to existing thread
- if (handOff_.offer(command, 0)) {
- return;
- }
- // 如果是工作线程不够,则增加W-T并执行command。
- // If cannot handoff and still under maximum, create new thread
- if (size < maximumPoolSize_) {
- addThread(command);
- return;
- }
- }
- }
- // 每次循环都执行BlockedExecutionHandler这个block Hook。
- // 默认行为是由调用execute的线程自己来执行command。
- // Cannot hand off and cannot create -- ask for help
- if (getBlockedExecutionHandler().blockedAction(command)) {
- return;
- }
- }//for
- }
worker 的工作
- /**
- * Class defining the basic run loop for pooled threads.
- **/
- protected class Worker implements Runnable {
- protected Runnable firstTask_;
- protected Worker(Runnable firstTask) { firstTask_ = firstTask; }
- public void run() {
- try {
- // 如果有默认的第一个command则执行它
- Runnable task = firstTask_;
- firstTask_ = null; // enable GC
- if (task != null) {
- task.run();
- task = null;
- }
- // 不断使用getTask()来获取 command (其实就是不断从Channel中取)。
- // 执行command
- while ( (task = getTask()) != null) {
- task.run();
- task = null;
- }
- }
- catch (InterruptedException ex) { } // fall through
- finally {
- // 结束时 执行
- workerDone(this);
- }
- }
- }
getTask是比较奥妙的地方。
- /**
- * Get a task from the handoff queue, or null if shutting down.
- **/
- protected Runnable getTask() throws InterruptedException {
- long waitTime;
- synchronized(this) {
- if (poolSize_ > maximumPoolSize_) // Cause to die if too many threads
- return null;
- waitTime = (shutdown_)? 0 : keepAliveTime_;
- }
- if (waitTime >= 0)
- return (Runnable)(handOff_.poll(waitTime));
- else
- return (Runnable)(handOff_.take());
- }