再聊线程池

关于线程池的介绍在http://blog.csdn.net/zero__007/article/details/43795287http://blog.csdn.net/zero__007/article/details/44102239 已经介绍了,这里只是稍微补充补充。

RejectedExecutionHandler

ThreadPoolExecutor的构造函数中会有该参数,表示拒绝策略。当队列满且线程池大小>=maximumPoolSize时会触发驳回,因为这时线程池已经不能响应新提交的任务,驳回时就会回调这个接口rejectedExecution方法,JDK默认提供了4种驳回策略,可以根据业务场景来选择,线程池的默认策略是AbortPolicy。

  • ThreadPoolExecutor.AbortPolicy:直接抛出运行时异常。
  • ThreadPoolExecutor.CallerRunsPolicy: 转成同步调用。
  • ThreadPoolExecutor.DiscardPolicy: 直接丢弃。
  • ThreadPoolExecutor.DiscardOldestPolicy: 取出队列的头并丢弃,重新提交该任务。

ThreadPoolExecutor预留了以下三个方法,我们可以通过继承该类来做一些扩展,比如监控、日志等等。

1
2
3
protected void beforeExecute(Thread t,  Runnable r) { }  
protected void afterExecute(Thread t, Runnable r) { }
protected void terminated() { }

ThreadPoolExecutor状态

RUNNING:初始状态,接受新任务并且处理已经在队列中的任务。

SHUTDOWN:不接受新任务,但处理队列中的任务。

STOP:不接受新任务,不处理排队的任务,并中断正在进行的任务。

TIDYING:所有任务已终止,workerCount为零,线程转换到状态TIDYING,这时回调terminate()方法。

TERMINATED:终态,terminated()执行完成。

Worker

​ ThreadPoolExecutor中重要的类是Worker:

1
2
3
4
5
6
7
8
9
10
11
12
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
// worker 所对应的线程
final Thread thread;
// worker所对应的第一个任务
Runnable firstTask;
/** Per-thread task counter */
// 已完成任务数量
volatile long completedTasks;
}

​ 该类继承了AQS与Runnable,其重载的run中会不断从queue中获取任务并执行。