Java并发包中的线程池
8.1介绍
线程池里面的线程是可以复用的
- 大量异步任务是线程池表现良好的性能
- 线程池提供了一种资源限制和管理的手段
线程池提供了许多可调参数和可扩展接口,
但是可以使用更加方便的Executors的工厂方法创建线程,不建议
8.2类图分析
Executors是一个工具类,提供了好多静态方法
线程池状态
Running:接受新任务并且处理阻塞队列里的任务
ShutDown:拒绝新任务但是处理阻塞队列里的任务
Stop:拒绝新任务并且抛弃阻塞队列里的任务,同时中断正在处理的热舞
Tidying:所有任务都执行为,再调用terminated方法
Terminated:终止状态
Running----ShutDown:显示调用shutdown方法,或者隐式调用finalize()方法
Running-=----Tidying:当线程池和任务队列维空是
Stop-----》Tidying:当线程池中维空时
Tidying----》terminated:当terminated()hook方法执行完成时
线程池参数
- corePoolSize:线程池核心线程个数
- workQueue:用户保存等待执行的任务和阻塞队列,比如上一章中的
- maximunPoolSize:线程池最大线程数量
- ThreadFactory:创建线程的工厂
- RejectedExecutionHandler:拒绝策略
- KeeyAliveTime:存活时间。如果当前线程池中的线程数量比核心线程数量多,并且是闲置状态,则这些闲置的线程能存活的最大时间
- TimeUnit:存活时间单位
线程池类型:
- newFixedThreadPool:创建一个核心线程个数和最大线程个数都为n Threads的新城池,并且阻塞对俩长度为Integer.Max_VAlue.keeyAliveTime=0说明只要线程个数比核心线程个数多并且当前空闲则回收
- newSingleThreadExecutor:创建也给核心线程数和最大线程数都为1的线程池,并且阻塞队列长度为很大
- newCacheThreadPool:创建一个按需创建的线程池,初始线程个数为0,最多线程数为很大,并且阻塞队列为同步队列。keeyAliveTime=60说明只要当前线程在60s秒内空闲则回收。
具体实现不知道
execute(线程)
提交任务
shutDown()
关闭,但是会等所有提交的任务执行完毕
shutDownNow()
线程池不再会接受新的任务,并且丢弃工作队列里面的任务,并且正在执行的也会被中断
awaitTermination
当前线程会被阻塞,直到线程池状态变成Terminated才返回
总结
线程池巧妙地使用一个Integer地原子类记录线程池状态和线程池中地线程个数,通过线程池状态控制任务地执行,每个Worker线程可以处理多个任务。线程池可以通过线程地复用减少了线程创建和销毁地开销
ScheduledThreadPoolExecutor原理探究
这是一个可以在指定一定延迟时间后或者定时进行任务调度执行地线程池
内部队列是一个DelayedWorkQueue队列,是一个延时队列
schedule(线程,long delay, TimeUnit unit)
提交一个延迟执行地任务,任务从提交时间算起延迟单位为uynit地delay时间后,开始执行,执行一次
scheduleWithFixedDelay(线程,long initialDelay, long delay, TimeUnit unit)
当任务执行完毕后,让其延迟固定时间后再次运行,initialDelay表示提交任务后延迟多少时间开始执行任务command,delay表示当任务执行完毕了多长时间后再次运行command,unit是时间单位。
任务会一直重复运行中抛出异常,被取消了,或者关闭了线程池。
scheduleAtFixedRate(线程, long initialDelay, long period, TimeUnit unit)
该方法相对起始时间点以固定频率调用指定地任务,当任务提交到新城池并延迟initialDelay时间后开始执行任务Command。然后从initialDelay + period时间点再次运行,然后再initialDelay + 2 * period时间点再次运行。循环往复,直到抛出异常或者取消任务。
小结
三种:
一种是延迟执行一次
二种是:再固定时间间隔内周期执行
三种是:保证固定地频率执行,如果没执行完,那就阻塞新的线程。