一、线程池的一些流程
线程池的主要处理流程
使用者 提交任务
|
条件 1.核心池已满? ==是==> 2.队列已满? ==是==> 3.线程池已满? ==是==> 按照策略执行不能处理的任务
|否 |否 |否
线程 创建线程执行任务 将任务存储到阻塞队列 创建线程执行任务
(addworker) 线程主要的步骤 需要获取全局锁,影响性能
线程池中线程执行任务分为两种情况,如下:
- 在execte()中创建一个新的线程(步骤1、3)
- 从阻塞队列中取
线程池的拒绝策略
- 直接抛出异常 AbortPolicy
- 只用调用者所在的线程来运行任务CallerRunsPolicy
- 对其队列里最老的一个任务,并执行任务DiscardOldestPolocy
- 不处理,丢弃掉DiscardPolicy
如何合理的配置线程池
分析任务特性
- 任务的性质:cpu密集型,IO密集型、混合型任务。CPU密集型的任务,应该配置尽可能小的线程,如配置num(cpu)+1个线程的线程池。由于IO密集型的任务并不是一直在执行任务,就可以尽可能多的配置线程数量如2*num(cpu)。对于混合型的任务,可以拆分成CPU密集型和IO密集型任务,只要这两个任务执行的时间差相差不是太大,那么分解后的吞吐量将高于串行时的吞吐量,如果二者相差很大,没必要拆解。
- 任务的优先级:可通过优先级阻塞队列PrioriBlockingQueue来处理。
- 任务的执行时间:处理时间短的任务先执行
- 任务的依赖性:是否依赖其他资源,如数据库连接,线程数应该设置大一点
- 建议使用有界队列,增加系统的稳定性和预警能力
线程池的监控
taskCount,completedTaskCount,largestPoolSize,poolsize,activiteCount
二、线程池的一些框架
//todo 阻塞队列,线程池框架