线程池
线程池的作用
- 降低资源的消耗
- 提高响应速度
- 提高线程的客观理性
当一个新任务到达线程池时,其处理流程?
- 1、线程池判断核心线程池的线程是否都在执行任务。
是:进入下个流程
否:创建一个新的工作线程来执行任务(需要加上全局锁)
工作线程:线程池创建线程时,会将线程封装成工作线程Worker,Worker在执行完任务后,还会循环获取工作队列里的任务来执行
- 2、线程池判断工作队列是否已满
是:进入下个流程
否:将新提交的任务存储在工作队列中
- 3、线程池判断线程池的线程是否都处于工作状态
是:交给饱和策略来处理
AbortPolicy:直接抛出异常(默认策略)
CallerRunsPolicy:只用调用者所在的线程来执行任务
DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务
DiscardPolicy:不处理,直接丢弃
否:创建新的工作线程来执行任务(需要加上全局锁)
介绍一下线程池的参数
- 1、corePoolSize:线程池的基本大小
当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即是其他空闲的基本线程能够执行新的任务,也会创建这个线程,等到需要执行的任务数大于线程池的基本大小的时候就不再创建
- 2、runnableTaskQueue:任务队列(用来保存等待执行任务的阻塞队列)
1、ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,进入队列的元素按照FIFO排序
2、LinkedBlockingQueue:一个基于链表的阻塞队列,元素按照FIFO排序,吞吐量通常要改于ArrayBlockingQueue,eg:Executors.newFixedThreadPool()
3、SynchronousQueue:一个不存储元素的阻塞队列,每个插入操作必须等到另一个进程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常高于LinkedBlockingQueue。eg:Executors.newCachedThreadPool()
4、PriorityBlockingQueue:一个具有优先级的无限阻塞队列
- 3、maximumPoolSize:线程池最大数量
线程允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。注意:如果是使用了上述的无界的任务队列,就没必要开启这个最大线程数的参数
- 4、ThreadFactory:用于设置创建线程的工厂
new ThreadFactoryBuilder().setNameFormat(“xxx-task–%d”).get();
- 5、RejectedExecutionHandler:饱和策略
AbortPolicy:直接抛出异常(默认策略)
CallerRunsPolicy:只用调用者所在的线程来执行任务
DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务
DiscardPolicy:不处理,直接丢弃
- 6、keepAliveTime:线程活动保持时间
线程池的工作线程空闲后,可以存活的最长时间
- 7、TimeUnit:线程活动保持时间的单位
存活时间的单位
如何向线程池中提交任务?
- 1、execute()方法
用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功。
- 2、submit()方法
用于提交需要返回值的任务,线程池会返回一个future对象,通过future对象可以判断任务是否执行成功,可以使用future.get()方法来获得返回值。
如何关闭线程池?
-
shutdown
-
shutdownNow
使用了上述两个中的任意一个,都会使得 isShutDown 返回 true。至所有任务都关闭后,表示线程池关闭成功,此时 isTerminated 会返回true
如何合理的配置线程池?
- 1、任务的性质
CPU密集型任务:尽可能配置小的线程,因为是一直在执行任务,无需一直进行线程的切换
IO密集型任务:并不是一直在执行任务,可以配置尽可能多的线程。
混合型任务:可以拆分成一个CPU密集型的任务和一个IO密集型的任务,只要是任务的相差时间不是很长,效率肯定会比未拆分之前要高。
- 2、任务的优先级
高
中
低
PriorityBlockingQueue
- 3、任务的执行时间
长
中
短
- 4、任务的依赖性
是否依赖其他的系统资源。eg:数据库连接
如何对线程池进行监控?
taskCount:线程池需要执行的任务的数量
completedTaskCount:线程池已经完成的线程的数量,总量应小于taskCount
largestPoolSize:线程池里曾经创建的最大线程数量,根据该值可以知道线程池之前是否满过,加入largestPoolSize等于线程池的最大大小,说明之前满过
getPoolSize:线程池的线程数量,只要是线程池不销毁的话,线程不会自动销毁,该值只增不减
getActiveCount:获取活动的线程数