线程池-6

try {

       Runnabler = timed ?

              workQueue.poll(keepAliveTime,TimeUnit.NANOSECONDS) :

              workQueue.take();

       if(r != null)

              returnr;

       timedOut= true;

} catch (InterruptedException retry) {

       timedOut= false;

}

继续走起,catch之后,timedOut = false,然后又回到①for循环中,再次判断线程池的状态②,前面走到interruptIdleWorkers时,线程池已是SHUTDOWN了,所以进入return null 分支,return null 之后重新回到runWorker,退出while循环,又进入到processWorkerExit方法了,然后继续tryTerminate –> interruptIdleWorkers…一个个地将闲置的线程回收,直至回收完成,线程池terminated。

for (;;) {                              //①

       intc = ctl.get();

       intrs = runStateOf(c);


       //Check if queue empty only if necessary.

       if(rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {             //②

              decrementWorkerCount();

              returnnull;

       }

整个线程池执行任务的流程就如上所述了。

接下来再来看看线程池的关闭:shutdown、shutdownNow。有了上面的基础这两个方法就很好理解了:

shutdown

     checkShutdownAccess(); //检查关闭线程池的权限

     advanceRunState(SHUTDOWN); //把线程池状态更新到SHUTDOWN

     interruptIdleWorkers(); //中断闲置的Worker

     onShutdown(); //钩子方法,默认不处理。ScheduledThreadPoolExecutor会做一些处理   

tryTerminate(); // 尝试结束线程池,上面已经分析过了



// shutdownNow方法会有返回值的,返回的是一个任务列表,而shutdown方法没有返回值

public List shutdownNow() {

   List tasks;

   final ReentrantLock mainLock = this.mainLock;

   mainLock.lock(); // shutdownNow操作也需要加锁,防止并发

   try {

       checkShutdownAccess(); //检查关闭线程池的权限

       advanceRunState(STOP); //把线程池状态更新到STOP

       interruptWorkers(); //中断Worker的运行

       tasks = drainQueue();

    }finally {

       mainLock.unlock(); //解锁

    }

   tryTerminate(); //尝试结束线程池,上面已经分析过了

   return tasks;

}


shutdownNow的中断和shutdown方法不一样,调用的是interruptWorkers方法:

然后这个方法调用的是interruptIfStarted

void interruptIfStarted() {

  Thread t;

   //Worker无论是否被持有锁,只要还没被中断,那就中断Worker

   if(getState() >= 0 && (t = thread) != null &&!t.isInterrupted()) {

      try {

          t.interrupt(); //强行中断Worker的执行

      } catch (SecurityException ignore) {

      }

   }

}

shutdown方法会更新状态到SHUTDOWN,不会影响阻塞队列里任务的执行,但是不会执行新进来的任务。同时也会回收闲置的Worker,直到任务全部执行完。

shutdownNow方法会更新状态到STOP,会影响阻塞队列的任务执行,也不会执行新进来的任务。同时会回收所有的Worker。

http://fangjian0423.github.io/2016/03/22/java-threadpool-analysis/

http://www.cnblogs.com/zhanjindong/p/java-concurrent-package-ThreadPoolExecutor.html

你可能感兴趣的:(线程池-6)