线程池
约 903 字大约 3 分钟
2025-01-22
1.线程池介绍
1.1 什么是线程池
线程池是一种利用池化技术思想来实现的线程管理技术,主要是为了复用线程、便利地管理线程和任务、并将线程的创建和任务的执行解耦开来。我们可以创建线程池来复用已经创建的线程来降低频繁创建和销毁线程所带来的资源消耗。
在JAVA中主要是使用ThreadPoolExecutor类来创建线程池,并且JDK中也提供了Executors工厂类来创建线程池(不推荐使用)。
1.2 线程池作用
- 降低资源消耗,复用已创建的线程来降低创建和销毁线程的消耗。
- 提高响应速度,任务到达时,可以不需要等待线程的创建立即执行。
- 提高线程的可管理性,使用线程池能够统一的分配、调优和监控。
1.3 线程池的核心参数
自定义线程池的7个核心参数
- 核心线程数大小(corePoolSize):核心线程不管空不空闲,都不会被回收除非设置了 核心线程的空闲存货时间,同时线程池需要保持该数量的线程
- 最大线程数(maximumPoolSize):线程池中最多允许创建线程的数量
- 存活时间(keepAliveTime)::如果超过存活时间,超过核心线程数的线程还没有接受到新的任务,那就回收该线程
- 存活时间的时间单位(unit)
- 存放待执行任务的队列(workQueue):当提交的任务数超过核心线程数大小后,再提交的任务就存放在这里。它仅仅用来存放被 execute 方法提交的 Runnable 任务
- 线程工厂(threadFactory):用来创建线程工厂
- 拒绝策略(handler):当最大线程数的线程都在工作时、同时等待队列里面放满了任务,这时继续提交的任务线程池就处理不了,应该执行怎么样的拒绝策略
讲完上面的 7 个参数后,我们需要关心的 3个参数:核心线程数、最大线程数、队列长度
问题:开发过程中线程池的核心线程数、最大线程数设置为多少?
1.3.1 静态核心线程数
线程池应用可以分为两种:计算密集型、IO密集型
- 计算密集型:核心线程数就是CPU核心数+1,在《Java并发编程实践》谈到——计算密集型的线程恰好在某时因为发生一个页错误或者因其他原因而暂停,刚好有一个“额外”的线程,可以确保在这种情况下CPU周期不会中断工作
- IO密集型:在IO操作时容易阻塞线程,可以设置更高的核心线程数,核心线程数 =
CPU 核心数 * (1 + 等待因子)
,其中等待因子取决于任务的 I/O 密集程度,一般取值范围是 1 到 5 之间
补充:获取当前机器上的处理器核心数:Runtime.getRuntime().availableProcessors()
1.3.2 动态核心线程数
问题:一个项目里面一般来说不止一个自定义线程池吧?比如有专门处理数据上送的线程池,有专门处理查询请求的线程池,这样去做一个简单的线程隔离。但是如果都用这样的参数配置的话,显然是不合理的