线程池和Executor框架
在并发编程中,线程是一种宝贵的资源。合理地创建和管理线程,不仅能提升程序性能,还能避免系统资源被耗尽。线程池(Thread Pool) 正是为此而生的利器。
什么是线程池
线程池可以理解为线程的容器或线程的管理者。它内部维护了一组可复用的线程,并通过合理调度来执行提交的任务,从而避免频繁创建和销毁线程的性能开销。
线程池由三部分组成:
- 核心线程(core thread)
- 线程池中始终保留的线程数,即使空闲也不回收。
- 非核心线程(临时线程)
- 当任务太多且核心线程都在忙,线程池会创建非核心线程来帮忙。
- 一段时间(
keepAliveTime)内空闲就会销毁。
- 任务队列(workQueue)
- 提交的任务如果所有线程都忙,就会被放入队列等待执行
为什么需要线程池?
降低频繁的创建线程和销毁线程
控制最大并发线程量
ThreadPoolExecutor 函数参数详解
1 | public ThreadPoolExecutor( |
注意: LinkedBlockingQueue 默认容量为 Integer.MAX_VALUE,不指定会有内存溢出的风险。
Executor框架和Executor工具类
Java 的线程池并非孤立存在,而是属于整个 Executor 框架。
Executor是 Java 并发包中的一套统一的线程池使用 API 接口规范,你可以理解为线程池的“控制台”。
- 核心接口:
Executor、ExecutorService - 常见实现类:
ThreadPoolExecutor(核心线程池实现)ScheduledThreadPoolExecutor(定时任务线程池)
| 接口 | 说明 |
|---|---|
Executor |
最顶层接口,定义 execute() |
ExecutorService |
扩展接口,支持 submit()、invokeAll() |
ScheduledExecutorService |
定时/周期执行任务接口 |
Executors 是一个工具类,提供常见线程池的工厂方法: |
1 | Executors.newFixedThreadPool(n); // 固定大小线程池 |
阿里巴巴开发者手册不推荐使用 Executors 创建线程池,建议直接使用 ThreadPoolExecutor 自定义参数,避免资源不可控。
为什么禁止使用Executors创建线程池?-阿里云开发者
代码举例
1 | public class ThreadPoolDemo { |
某一次运行结果
1 | 任务 0 由线程 pool-1-thread-1 执行 |
注意,如果在这里你有这样的疑问:
为什么不是任务0,任务1···这样顺序的进行?
这是因为CPU调度问题,先开始的线程不一定先执行完成。
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.