JAVA:简单易懂记住线程池(一)
·
1. 什么是线程池?
线程池就像是一个线程管理工厂,它可以:
-
预先创建一些线程放在"池子"里
-
当有任务时,复用这些线程,而不是创建新线程
-
任务完成后,线程不销毁,等待下一个任务
线程池工作流程(生动形象版)
想象一个银行窗口系统:
任务到来时:
1. 先看"正式窗口"(核心线程)有没有空闲 → 有空就用
2. 如果正式窗口都忙,任务去"等待区"(工作队列)排队
3. 如果等待区也满了,呼叫"临时窗口"(创建新线程直到最大线程数)
4. 如果所有窗口都忙,等待区也满了 → 执行"拒绝策略"
5. 忙完后,临时窗口空闲超过指定时间就关闭
2. 为什么要用线程池?
没有线程池的问题:
// 每次任务都创建新线程
new Thread(() -> {
// 执行任务
}).start();
-
频繁创建/销毁线程 → 消耗资源
-
线程数量不可控 → 可能创建过多线程导致系统崩溃
使用线程池的好处:
-
资源复用:线程可重复使用
-
控制并发数:避免线程过多
-
提高响应速度:线程已创建好,无需等待
-
统一管理:方便监控和调优
3. 线程池核心组件(类比公司)
|
组件 |
类比公司部门 |
作用 |
|---|---|---|
|
corePoolSize(核心线程数) |
正式员工 |
最少要保持的线程数量 |
|
maximumPoolSize(最大线程数) |
总编制(正式+临时) |
最多可创建的线程数 |
|
workQueue(工作队列) |
待办任务列表 |
存放等待执行的任务 |
|
threadFactory(线程工厂) |
HR部门 |
线程工厂,用于创建线程 |
|
handler(拒绝策略处理器) |
拒绝接待 |
任务太多时的处理方式 |
|
keepAliveTime(存活时间) |
临时工合同期 |
非核心线程空闲存活时间 |
4. 创建线程池的简单方式
4.1 Executors工厂类(快捷方式)
// 1. 固定大小的线程池(正式员工固定)
ExecutorService fixedPool = Executors.newFixedThreadPool(5);
// 2. 单线程线程池(只有1个员工)
ExecutorService singlePool = Executors.newSingleThreadExecutor();
// 3. 可缓存的线程池(忙时招人,闲时裁员)
ExecutorService cachedPool = Executors.newCachedThreadPool();
// 4. 定时任务线程池(做计划任务的)
ScheduledExecutorService scheduledPool =
Executors.newScheduledThreadPool(3);
4.2 ThreadPoolExecutor(自定义创建)
ThreadPoolExecutor pool = new ThreadPoolExecutor(
5, // 核心线程数:最少5个"正式工"
10, // 最大线程数:最多10个员工(5正式+5临时)
60, // 临时工空闲60秒后解雇
TimeUnit.SECONDS, // 时间单位:秒
new ArrayBlockingQueue<>(100), // 任务队列:最多存100个任务
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);
5. 四种拒绝策略
// 1. 直接抛出异常(默认)
new ThreadPoolExecutor.AbortPolicy();
// 2. 谁提交的任务谁自己执行
new ThreadPoolExecutor.CallerRunsPolicy();
// 3. 丢弃队列中最老的任务
new ThreadPoolExecutor.DiscardOldestPolicy();
// 4. 直接丢弃新任务(静默丢弃)
new ThreadPoolExecutor.DiscardPolicy();
后边会单独写一下不同线程池的使用、工作队列和拒绝策略。
更多推荐


所有评论(0)