网站首页 > java教程 正文
1. 为什么要使用线程池
线程池的工作主要是控制线程的数量。处理过程中将任务放入等待队列,然后在线程创建后执行这些任务。
优点:线程复用,控制最大并发数,管理线程
2. JDK提供的线程池
主要关注两个类:
ThreadPoolExecutor:线程池核心类
Executors:创建线程池的工具类
通过Executors工具类创建线程池的3种方式
- 创建线程数固定的线程池
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
- 创建单线程的线程池
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
Single线程池可以理解为Fixed线程池的特例
- 创建可缓冲线程的线程池
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
通过ThreadPoolExecutor核心类创建线程池的方式
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
ThreadPoolExecutor构造方法的7大参数
corePoolSize:线程池中常驻的核心线程数
maximumPoolSize:线程池中可容纳的最大线程数
keepAliveTime:空闲的临时线程的存活时间(当线程池中的线程数量超过corePoolSize时,临时创建的线程如果空闲时长达到keepAliveTime,那么该临时线程将被销毁,直到只剩corePoolSize个线程为止)
unit:keepAliveTime的单位
workQueue:缓存任务的队列
threadFactory:创建线程的工厂
handler:拒绝策略(当缓存队列已满,且线程池中的线程数也达到了最大线程数,此时应该采用何种策略拒绝新来的任务)
3. 线程池底层逻辑
- 线程池初始化后不会立即创建线程,而是等到有任务来时才创建核心线程。
- 当线程池中核心线程数已满后并不会立即扩容线程池,而是把任务放到等待队列中。
- 当等待队列已满后,创建临时线程执行任务,直到总线程数达到maximumPoolSize为止。
- 如果等待队列已满且总线程数达到最大值后还有任务进来,则按照设置的拒绝策略处理。
- 当总线程数大于核心线程数时,空闲的临时线程等待keepAliveTime(unit)后将自动销毁。
4. 线程池需要手工创建
JDK中的Executors工具类定义了一些快捷地创建线程池的方法,但是《阿里巴巴Java开发手册》中提到,我们应该禁止使用这些方法来创建线程池,而应该手动通过new ThreadPoolExecutor来创建线程池。
原因如下:
(七) 并发处理
4.【强制】线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors返回的线程池对象的弊端如下:
1) FixedThreadPool和SingleThreadPool:
允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。
2) CachedThreadPool:
允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。
猜你喜欢
- 2025-05-23 Java线程池:核心参数与最佳实践
- 2025-05-23 深入理解 Java 的线程池原理
- 2025-05-23 面试突击34:如何使用线程池执行定时任务?
- 2025-05-23 Java线程池核心参数调优指南:掌控并发世界的钥匙
- 2025-05-23 Java线程池:优雅管理并发任务的艺术
- 2025-05-23 一篇文章快速搞懂Java中常用的四种线程池
- 2025-05-23 Java线程池工作原理深度解读:从创建到任务执行的全过程
- 2025-05-23 一文看懂:Java线程池任务拒绝机制解析
- 2025-05-23 Java线程池配置与监控:掌控并发世界的钥匙
- 2025-05-23 Java线程池解读:从入门到精通,核心参数全掌握!
你 发表评论:
欢迎- 05-23Java线程池:核心参数与最佳实践
- 05-23深入理解 Java 的线程池原理
- 05-23面试突击34:如何使用线程池执行定时任务?
- 05-23Java线程池核心参数调优指南:掌控并发世界的钥匙
- 05-23Java线程池:优雅管理并发任务的艺术
- 05-23一篇文章快速搞懂Java中常用的四种线程池
- 05-23Java线程池工作原理深度解读:从创建到任务执行的全过程
- 05-23一文看懂:Java线程池任务拒绝机制解析
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)