线程池:
- 避免系统频繁的创建和销毁线程;
- 提高创建线程进行复用;
ThreadPoolExecutor
方法 | 返回值 | 解释 |
newFixedThreadPool(int nThreads) | ExecutorService | 固定线程数量的线程池;无空闲线程,任务暂存任务队列中,待有空闲线程便处理在任务队列中的线程 |
newSingleThreadExecutor() | ExecutorService | 一个只有一个一个线程的线程池。其他同上 |
newCachedThreadPool() | ExecutorService | 根据实际情况调整线程池;无空闲线程有任务处理则新建线程。所有线程任务执行完毕后,返回线程池进行复用 |
newSingleThreadScheduledExecutor() | ScheduleExecutorService | 大小为1的线程池,可以定时执行某个任务 |
newScheduledThreadPool(int corePoolSize) | ScheduledExecutorService | 可以指定线程数量的线程池 |
计划任务:newScheduledThreadPool
- scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit);
- 第一个人任务执行时间initialDelay+period,第二个任务initialDelay+2*period 依次类推 如果第一个任务延期完成,第二个任务会在第一个任务结束后立即执行
- scheduleWithFixedDelay(Runnable command,long initialDelay,long period,TimeUnit unit);
- 定期的执行任务;period 值
注:如果任务执行遇到异常,后续的子任务都会停止调度;保证异常及时处理
以上线程池内部实现
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)
corePoolSize:线程池中的线程数量。
maximumPoolSize:线程池中的最大线程数量
keepAliveTime:线程池数量超过corePoolSize,多余的空闲线程的存活时间。
unit:keepAliveTime 单位。
workQueue:任务队列,被提交单尚未被执行的任务。
threadFactory:线程工厂,用于创建线程,一般默认。
handler:拒绝策略。当任务太多来不及处理,如何拒绝任务。
针对workQueue参数 有以下任务队列
SynchronousQueue:直接提交的队列。每一个插入操作都要等待一个相应的删除操作,提交的新任务交给线程执行,如果没有空闲的进程,则尝试创建新的进程,如果进程数量 已经达到最大值,则执行拒绝策略。通常要设置很大的maximumPoolSize值,否则容易执行拒绝策略。
ArrayBolckingQueue:有界的任务队列,构造函数必带一个容量参数,表示队列最大容量。新任务执行,如果线程池的实际线程数小于corePoolSize,则会有限创建新的线程,若大于corePoolSize,则新任务加入等待队列。若队列满无法加入,则在总线程数不大于maximumPoolSize的前提下,创建新的进程执行任务。若大于执行拒绝策略。(有限保证核心线程数维持在corePooleSize)
LinkedBlockingQueue:无界任务队列。除非资源耗尽不存在任务入队失败情况。新任务到来,若小于corePoolSize是,线程池会生成新的线程执行任务,当系统线程资源达到corePoolSize后,就不会继续增加。若后续仍有新的任务加入,而又没有空闲的线程资源,则任务直接进入队列等待。若任务创建和处理的速度差异很大,无限队列会快速增长直到耗尽系统内存。(一般设置corePoolSize和maximumPoolSize一样大)
PriorityBlockingQueue:优先任务队列。特殊的无界队列。根据任务自身的优先级顺序先后执行任务。
注:使用自定义线程池时,要根据饮用的具体情况,选择合适的并发队列作为任务的缓冲。当线程资源紧张时,不同的并发队列对系统行为和性能的影响均不同。
jdk内置 handler 拒绝策略:
AbortPolicy 策略:该策略会直接抛出异常,阻止系统正常工作。(默认策略)
CallerRunsPolicy 策略:只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的任务。显然这样做不会真的丢弃任务,但是,任务提交线程的性能极有可能会急剧下降。
DiscardOledestPolicy 策略:该策略将丢弃最老的一个请求,也就是即将被执行的一个任务,并尝试再次提交当前任务。
DiscardPolicy 策略:该策略默默地丢弃无法处理的任务,不予任何处理。如果允许任务丢失,我觉得这可能是最好的一种方案了吧。
注:以上内置策略实现RejectedExecutionHandler 接口,若以上策略仍无法满足实际应用,可以自己扩展
线程池自定义:ThreadPoolExecutor 扩展(beforeExecute(Thread t,Runnable r),afterExecute(Runnable r,Throwable t),terminated())
自定义线程创建:ThreadFactory
分而治之:fork/join
ForkJoinPool 线程池
ForkJoinTask 线程池