Java的线程池相关的几个问题
1.Java线程池参数
Java线程池(ThreadPoolExecutor)通过6个核心参数来控制线程的创建、任务调度和资源管理:
1.corePoolSize(核心线程数)
- 线程池中始终保持存活的线程数量,即使空闲也不会被销毁(除非设置allowCoreThreadTimeOut为true)。
- 建议配置:
- CPU密集型任务(如计算、加密):corePoolSize = CPU核心数(或CPU核心数 + 1)。
- IO密集型任务(如数据库查询、网络请求):corePoolSize = CPU核心数 × (1 + IO耗时/CPU耗时)。
2.maximumPoolSize(最大线程数)
- 线程池允许创建的最大线程数,当任务队列满了且当前线程数小于maximumPoolSize时,会创建新线程。
- 建议配置:
- CPU密集型:maximumPoolSize = corePoolSize(避免过多线程竞争CPU)。
- IO密集型:maximumPoolSize = corePoolSize × 2~4(允许更多线程等待IO)。
3.keepAliveTime(线程空闲时间)
- 非核心线程空闲时的存活时间,超时后会被回收。
- 默认值:60秒,可结合TimeUnit调整(如TimeUnit.SECONDS)。
4.workQueue(任务队列)
- 存放待执行任务的阻塞队列,常见类型:
- LinkedBlockingQueue(无界队列,可能导致OOM)。
- ArrayBlockingQueue(有界队列,需设置合理容量)。
- SynchronousQueue(直接移交任务,不存储)。
5.threadFactory(线程工厂)
- 自定义线程创建方式(如命名、优先级、守护线程设置)。
6.rejectedExecutionHandler(拒绝策略)
- 当任务队列满且线程数达到maximumPoolSize时触发的策略:
- AbortPolicy(默认):抛出RejectedExecutionException。
- CallerRunsPolicy:由提交任务的线程直接执行。
- DiscardPolicy:静默丢弃任务。
- DiscardOldestPolicy:丢弃队列最旧任务,重试提交。
2.如何合理配置核心线程数?
1.CPU密集型任务(如加密、计算)
- 公式:corePoolSize = CPU核心数(如8核CPU设为8)。
- 原因:过多线程会增加上下文切换开销,降低性能。
2.IO密集型任务(如数据库、HTTP请求)
- 公式:corePoolSize = CPU核心数 × (1 + IO耗时/CPU耗时)。
- 示例:若IO耗时占80%,则corePoolSize = 8 × (1 + 4) = 40。
3.混合型任务
- 根据实际测试调整,监控CPU使用率和线程池队列堆积情况。
3.任务队列满了会怎样处理?
1.未达maximumPoolSize
- 线程池会创建新线程处理任务(直到maximumPoolSize)。
2.已达maximumPoolSize
- 触发拒绝策略(如AbortPolicy抛异常,CallerRunsPolicy回退到调用线程执行)。
3.优化建议
- 使用有界队列(如ArrayBlockingQueue)避免OOM。
- 结合监控工具(如Prometheus、JMX)动态调整队列容量和线程数。