ThreadPoolExecutor:使用给定的初始参数和默认线程工厂和拒绝的执行处理程序创建一个新的线程池执行器
一 构造方法参数说明
有四个构造方法,最终都是调用构造方法四
构造方法参数说明: @param corePoolSize: 保留在池中的线程数,即使它们是空闲的,除非allowCoreThreadTimeOut被设置 @param maximumPoolSize: 池中允许的最大线程数 @param keepAliveTime :当线程数大于核心时,这是多余的空闲线程在终止之前等待新任务的最大时间 @param unit: keepAliveTime参数的时间单位 @param workQueue: 用于在任务执行之前保存任务的队列。这个队列将只保存由execute方法提交的Runnable任务 @param threadFactory: 当执行器创建一个新线程时使用的工厂 @param handler: 由于达到线程边界和队列容量而阻塞执行时使用的处理程序 |
构造方法一
构造方法二
构造方法三
构造方法四
二 RejectedExecutionHandler说明
由于达到线程边界和队列容量而阻塞执行时使用的处理程序,如果不指定则默认AbortPolicy
private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();
AbortPolicy(默认) |
直接抛出RejectedExecutionException异常 |
CallerRunsPolicy |
直接调用线程处理 |
DiscardPolicy |
什么都不做丢弃被拒绝的任务 |
DiscardOldestPolicy |
丢弃最老的未处理请求然后重试的被拒绝的任务 |
三 BlockingQueue<Runnable> 工作队列介绍
用于在任务执行之前保存任务的队列,共有七个实现类
ArrayBlockingQueue |
由数组支持的有界阻塞队列。该队列对元素进行FIFO(先进先出)排序。队列头是在队列中停留时间最长的元素。队列的尾部是在队列中时间最短的元素。新元素插入到队列的尾部,队列检索操作获取队列头部的元素。 |
DelayQueue |
一种由延时元素组成的无界阻塞队列,其中一个元素只能在其延迟过期时被获取。队列的头是delay元素,它的延迟在过去过期的时间最长。如果没有过期的延迟,则没有头部,poll将返回null。当元素的getDelay(TimeUnit.NANOSECONDS)方法返回一个小于或等于0的值时,就会发生过期。即使不能使用take或poll删除未过期的元素,它们也会被视为普通元素。例如,size方法返回过期和未过期元素的计数。这个队列不允许空元素。 |
LinkedBlockingQueue |
基于链接节点的可选边界阻塞队列。该队列对元素进行FIFO(先进先出)排序。队列头是在队列中停留时间最长的元素。队列的尾部是在队列中时间最短的元素。新元素插入到队列的尾部,队列检索操作获取队列头部的元素。链接队列通常比基于数组的队列具有更高的吞吐量,但在大多数并发应用程序中性能较难以预测。 |
LinkedBlockingDeque |
基于链接节点的可选边界阻塞deque |
LinkedTransferQueue |
基于链接节点的无界TransferQueue。该队列针对任何给定的生产者对元素进行FIFO(先进先出)排序。队列头是某个生产者在队列中待的时间最长的元素。队列的尾部是某个生产者在队列上停留的时间最短的元素。 |
PriorityBlockingQueue |
一个无界阻塞队列,它使用与类PriorityQueue相同的排序规则并提供阻塞检索操作。虽然这个队列在逻辑上是无界的,但是试图添加的内容可能会由于资源耗尽而失败(导致OutOfMemoryError)。该类不允许空元素。依赖于自然排序的优先级队列也不允许插入不可比较的对象(这样做会导致ClassCastException)。 |
SynchronousQueue |
一个阻塞队列,其中每个插入操作必须等待另一个线程的相应删除操作,反之亦然。同步队列没有任何内部容量,甚至连一个容量都没有。您无法窥视同步队列,因为只有当您试图删除某个元素时,它才会出现;你不能插入一个元素(使用任何方法),除非另一个线程试图删除它;你不能迭代,因为没有什么需要迭代的。队列头是第一个加入队列的线程试图添加到队列中的元素;如果没有这样的队列线程,那么就没有可以删除的元素,poll()将返回null。对于其他Collection方法(例如contains), SynchronousQueue充当一个空集合。这个队列不允许空元素。 |
四 ThreadFactory到底有什么作用呢?
ThreadFactory是一个接口,接口中只有一个newThread方法;可以写一个此接口的实现类,此实现类最重要的一个作用就是设置线程名称,多线程调试起来本来就费劲,如果没有标识符,那就更难了。所以这个功能还是很重要的,并且也是编码规范中推荐的。当然实现类的写法可以多种多样,如果不指定线程工厂实现类,会使用JDK默认的DefaultThreadFactory