来聊聊线程池

本文深入探讨Java线程池技术,包括线程池的类型、创建参数、应用场景及设计思路。解析五种常见线程池特性,如newCacheThreadPool的缓存机制,newFixedThreadPool的固定线程数管理,以及如何避免任务堆积和过度扩展线程等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程池可以说是在Java代码中非常常见的技术了,利用线程池技术可以有效的提高系统资源的使用效率,本文将从线程池的类型分类、创建线程池参数、各种类型线程池的使用场景、优秀的设计思路等
这里写图片描述

Executor 为基础接口,设计初衷是将任务提交和任务执行细节解耦
ExecutorService 则更加完善,不仅提供了service管理功能,也提供了更加全面的提交任务机制
Executors 提供了各种工厂方法,简化使用

下面我们来分析一下5中线程池创建

  • newCacheThreadPool()
    一种用来处理大量短时间工作任务的线程池,具有几个特点:他会试图缓存线程并重用,当无缓存线程可用时,会创建新的线程,如果闲置时间超过60秒,则被终止并移出缓存,内部使用SynchronousQueue作为工作队列
  • newFixedThreadPool(int nThreads)
    重用指定数目的线程,背后使用无界队列,任何时候最多只有nThreads
    个活跃的线程,超过的就会放进阻塞队列中

  • newSingleThreadExecutor()
    特点是工作线程只有一个,操作无界队列,保证任务串行执行,单例实现,最多只有一个线程处于活跃状态

  • newSingleThreadScheduleExecutor(int n)
    可以调整工作线程数,适用于进行定时或者周期性调度工作

  • newWorkStealingPool(int n)
    内部使用fork/join 基于工作窃取模式并行执行

内部工作线程基于AQS实现
线程池中的生命周期还有状态都是通过 ctl 那个变量来体现,一种高效优化的体现
通过高低位的不同,既表示线程池状态,又表示工作线程数目,可以有效的免去操作不同变量同步开销
下图为线程池的状态流转图
这里写图片描述

线程池实践,我会列举一些常见需要避免的问题

  • 避免任务堆积。因为任务都在内存中,堆积可能会导致OOM
  • 避免过度扩展线程,即应该设定一下最大活跃线程数量的上限
  • 警惕线程数量的不断增涨
  • 避免死锁
  • 在使用线程池时不应该使用ThreadLocal

线程池的大小选择

  • 计算密集型的话 建议 CPU核数 或者核数加一
  • I/O操作比较多的话 推荐公式
    • 线程数 = CPU 核数 * (1 + 平均等待时间 / 平均工作时间)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值