- 在服务器负载过大,如何让新的线程等待或者友好的拒绝服务?
- 简单方式使用线程池
- 开源技术guava、hystrix
- 线程池的基本作用
- 利用线程池管理并复用线程、控制最大并发数
- 实现任务线程队列缓存策略和拒绝机制
- 实现某些与时间相关的功能
- 隔离线程环境
- ThreadPoolExecutor核心参数
- corePoolSize
- 常驻核心线程数
- 等于0,任务执行完即销毁
- 大于0,任务执行完,核心线程也不会被销毁
- maximumPoolSize
- 线程池能容纳同时执行的最大线程数
- 如果待执行的线程数大于此值,需要借助workQueue缓存在队列中。
- keepAliveTime
- 线程池中的线程空闲时间
- 空闲线程达到这个值时,线程会被销毁,直到只剩下corePoolSize个线程为止
- 避免浪费内存和句柄资源
- TimeUnit
- 时间单位
- keepAliveTime时间单位通常时秒
- workQueue
- 缓存队列
- 请求线程数大于maximumPoolSize时,线程进入BlockingQueue阻塞队列。是一个生产消费模型队列。
- threadFactory
- handler
- 执行拒绝策略的对象
- 当超过workQueue的任务缓存区上限后,就可以通过该策略处理请求,这是一种简单的限流保护。
- 三种友好的拒绝策略
- 保存到数据库进行削峰填谷,空闲时再提取出来
- 转向某个提示页面
- 打印日志
- Executors的5个核心方法
- newSingleThreadPool
- 保证按任务的提交顺序依次执行
- 无界队列,瞬时请求非常大,会有OOM风险
- 返回ThreadPoolExecutor线程池对象
- newFixedThreadPool
- 核心线程数也是最大可执行线程数
- 不存在空闲线程
- keepAliveTime等于0
- 无界队列,瞬时请求非常大,会有OOM风险
- 返回ThreadPoolExecutor线程池对象
- newCachedThreadPool
- maximumPoolSize最大可以至Integer.MAX_VALUE,如果达到这个上限,没有任何服务器能够正常工作,存在OOM风险。
- 回收工作线程
- 返回ThreadPoolExecutor线程池对象
- newScheduledThreadPool
- 线程数最大可以至Integer.MAX_VALUE,存在OOM风险
- 不回收工作线程
- 返回ScheduledThreadPoolExecutor线程池对象
- newStealingThreadPool
- JDK8引入的新线程池对象
- 支持给定的并行度,默认CPU数量
- 使用多个队列减少竞争
- 返回ForkJoinPool线程池对象
- 自定义实现ThreadFactory
- 一定要有特定意义的名称,方便问题回溯
- 统一用newThread获取线程
- 自定义实现RejectedExecutionHandler
- 使用线程池注意事项
- 合理设置线程池参数,根据实际业务场景来决定工作线程数
- 线程资源必须通过线程池提供,不允许在应用中自行显示创建线程
- 不允许使用Executors
- 推荐直接使用ThreadPoolExecutor的方式创建,这样能更加明确线程池的运行规则,避免资源耗尽。
- 创建线程或线程池要指定有意义的名字,方便问题回溯
线程池技术
原文:https://www.cnblogs.com/bee4j/p/10291476.html