网站首页 > java教程 正文
Java 线程池(Thread Pool)是一种创建和管理线程的机制,旨在优化线程资源使用,提高应用程序的性能和响应速度。Java 的 java.util.concurrent 包中提供了线程池的实现,主要通过 Executor 接口及其实现类来管理。
1. 为什么需要线程池?
- 减少资源消耗:线程的创建和销毁会消耗系统资源,线程池通过复用线程减少资源浪费。
- 提高响应速度:线程池可以在任务到达时立即提供线程,而不需要等待新线程的创建。
- 增强可管理性:线程池可以有效管理线程的数量,避免因大量线程导致系统资源耗尽。
2. Java 线程池核心类
Java 中的 Executor 框架提供了线程池相关的接口和类,主要包括:
- Executor:顶层接口,定义了任务提交的方法 execute(Runnable command)。
- ExecutorService:继承自 Executor,提供了管理线程池的方法,例如 submit()、shutdown() 等。
- ThreadPoolExecutor:ExecutorService 的实现类,具备灵活的线程池配置。
- Executors:工厂类,提供了各种类型的线程池创建方法。
3. 线程池的核心参数
ThreadPoolExecutor 是线程池的核心实现,具有以下重要参数:
java
复制代码
public ThreadPoolExecutor(
int corePoolSize, // 核心线程数
int maximumPoolSize, // 最大线程数
long keepAliveTime, // 空闲线程的存活时间
TimeUnit unit, // 空闲线程存活时间的单位
BlockingQueue<Runnable> workQueue, // 阻塞队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler // 拒绝策略
)
- corePoolSize:核心线程数,表示线程池在空闲时仍保留的线程数量。
- maximumPoolSize:最大线程数,表示线程池能够容纳的最大线程数量。
- keepAliveTime:非核心线程的最大空闲时间,当线程空闲超过此时间时会被回收。
- unit:keepAliveTime 的时间单位。
- workQueue:任务队列,存储等待执行的任务。
- threadFactory:线程工厂,用于创建新线程。
- handler:拒绝策略,当任务无法处理时的应对措施。
4. 线程池的工作流程
线程池在处理任务时遵循以下流程:
- 判断线程数是否达到核心线程数:若未达到,创建新线程执行任务。
- 核心线程数已满:将任务加入到任务队列中等待执行。
- 任务队列已满:若线程数小于最大线程数,创建新线程执行任务。
- 线程数达到最大值,且任务队列也已满:根据拒绝策略来处理任务。
5. 常见的线程池类型
Java 提供了 Executors 工厂类,帮助创建几种常见的线程池。
1.newFixedThreadPool(int nThreads)
创建一个固定大小的线程池,线程池中的线程数量保持不变。适合执行长期任务,避免频繁创建销毁线程。
java
复制代码
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
2.newCachedThreadPool()
创建一个可缓存的线程池,线程池根据需要自动扩容,空闲线程超过 60 秒会自动销毁。适合处理大量短期任务。
java
复制代码
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
3.newSingleThreadExecutor()
创建一个单线程的线程池,确保所有任务都在同一线程中按顺序执行,适用于需要串行执行任务的场景。
java
复制代码
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
4.newScheduledThreadPool(int corePoolSize)
创建一个线程池,可以按时间安排执行任务,支持定时和周期性任务。
java
复制代码
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
6. 线程池的拒绝策略
当线程池无法处理新的任务时,可以采取以下拒绝策略:
- AbortPolicy(默认):抛出 RejectedExecutionException 异常。
- CallerRunsPolicy:由调用线程来执行任务。
- DiscardPolicy:直接丢弃任务,不抛异常。
- DiscardOldestPolicy:丢弃队列中最旧的任务,尝试重新提交当前任务。
示例:
java
复制代码
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, 4, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
7. 线程池的管理和关闭
- shutdown():平滑关闭线程池,不再接受新任务,等待所有已提交任务完成后关闭。
- shutdownNow():立即关闭线程池,试图停止所有执行中的任务并返回等待执行的任务列表。
java
复制代码
executor.shutdown();
8. 实际示例
以下是一个使用 ThreadPoolExecutor 的示例:
java
复制代码
import java.util.concurrent.*;
public class ThreadPoolExample {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, 4, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy()
);
for (int i = 1; i <= 10; i++) {
final int taskNumber = i;
executor.execute(() -> {
System.out.println("Executing task " + taskNumber + " by " + Thread.currentThread().getName());
try {
Thread.sleep(1000); // 模拟任务耗时
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executor.shutdown();
}
}
9. 线程池使用注意事项
- 线程数控制:合理设置 corePoolSize 和 maximumPoolSize,避免过多线程导致系统资源耗尽。
- 选择合适的队列:ArrayBlockingQueue(有界队列)、LinkedBlockingQueue(无界队列)适用于不同的场景。
- 避免任务阻塞:长时间运行的任务会占用线程资源,建议分解任务或使用 Future 进行异步处理。
- 优先使用工厂方法:Java 8 引入的 Executors.newWorkStealingPool() 可以创建一种并行度较高的线程池,适合处理并行流任务。
线程池是 Java 并发编程中的重要工具,合理配置线程池参数可以有效提升应用性能,并避免系统资源的浪费或过载。
- 上一篇: java线程池创建方式
- 下一篇: Java线程池原理全面详解(图文版)
猜你喜欢
- 2024-11-23 不清楚Java线程池实现原理?那你应该收藏这篇文章!「源码分析」
- 2024-11-23 Java基础——Java多线程(线程的创建方式)
- 2024-11-23 「一文搞懂」Java线程池实现原理
- 2024-11-23 Java线程池
- 2024-11-23 java线程池实现原理以及应用场景说明
- 2024-11-23 快速弄懂Java线程池
- 2024-11-23 java线程池原理浅析
- 2024-11-23 彻底了解线程池的原理——40行从零开始自己写线程池
- 2024-11-23 Java并发编程(8):Executor框架 - 可扩展线程池WorkStealingPool
- 2024-11-23 java中的线程池
你 发表评论:
欢迎- 最近发表
-
- 五,网络安全IDA Pro反汇编工具初识及逆向工程解密实战
- 「JAVA8」- Lambda 表达式(java lambda表达式原理)
- 深入探讨Java代码保护:虚拟机保护技术的新时代
- Nginx反向代理原理详解(图文全面总结)
- 逆向拆解日本IT,哪些Java技术栈薪资溢价高
- mybatis 逆向工程使用姿势不对,把表清空了,心里慌的一比
- Spring Boot集成ProGuard轻松实现Java 代码混淆, Java 应用固若金汤
- 从 Java 代码逆向工程生成 UML 类图和序列图
- 人与人相处:尊重是标配,靠谱是高配,厚道是顶配
- Windows系统安装日期如何修改(windows10怎么修改安装日期)
- 标签列表
-
- 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)
本文暂时没有评论,来添加一个吧(●'◡'●)