线程池
1 问题
像性能池对吧?一般一个性能池的一个正常工作原理是什么样的?
它里面有哪些核心的参数呢?这些参数是怎么配合做工作的呢?
2 第一种回答
任务提交 → 核心线程执行 → 任务队列缓存 → 非核心线程执行 → 拒绝策略处理。
第一步,线程池通过 submit() 提交任务。
ExecutorService threadPool = Executors.newFixedThreadPool(5);
threadPool.submit(() -> {
System.out.println(Thread.currentThread().getName() + "\t" + "办理业务");
});
第二步,线程池会先创建核心线程来执行任务。
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true)) {
return;
}
}
第三步,如果核心线程都在忙,任务会被放入任务队列中。
workQueue.offer(task);
第四步,如果任务队列已满,且当前线程数量小于最大线程数,线程池会创建新的线程来处理任务。
if (!addWorker(command, false))
第五步,如果线程池中的线程数量已经达到最大线程数,且任务队列已满,线程池会执行拒绝策略。
handler.rejectedExecution(command, this);
第二种回答
第一步,创建线程池。
第二步,调用线程池的 execute()方法,准备执行任务。
- 如果正在运行的线程数量小于 corePoolSize,那么线程池会创建一个新的线程来执行这个任务;
- 如果正在运行的线程数量大于或等于 corePoolSize,那么线程池会将这个任务放入等待队列;
- 如果等待队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么线程池会创建新的线程来执行这个任务;
- 如果等待队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会执行拒绝策略。
第三步,线程执行完毕后,线程并不会立即销毁,而是继续保持在池中等待下一个任务。
第四步,当线程空闲时间超出指定时间,且当前线程数量大于核心线程数时,线程会被回收。
class ThreadPoolDemo {
public static void main(String[] args) {
// 创建一个线程池
ExecutorService threadPool = new ThreadPoolExecutor(
3, // 核心线程数
6, // 最大线程数
0, // 线程空闲时间
TimeUnit.SECONDS, // 时间单位
new LinkedBlockingQueue<>(10), // 等待队列
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);
// 模拟 10 个顾客来银行办理业务
try {
for (int i = 1; i <= 10; i++) {
final int tempInt = i;
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName() + "\t" + "办理业务" + tempInt);
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
threadPool.shutdown();
}
}
}
参数间的配合
线程池有 7 个参数,需要重点关注的有核心线程数、最大线程数、等待队列、拒绝策略。
①、corePoolSize:核心线程数,长期存活,执行任务的主力。
②、maximumPoolSize:线程池允许的最大线程数。
③、workQueue:任务队列,存储等待执行的任务。
④、handler:拒绝策略,任务超载时的处理方式。也就是线程数达到 maximumPoolSiz,任务队列也满了的时候,就会触发拒绝策略。
⑤、threadFactory:线程工厂,用于创建线程,可自定义线程名。
⑥、keepAliveTime:非核心线程的存活时间,空闲时间超过该值就销毁。
⑦、unit:keepAliveTime 参数的时间单位:
TimeUnit.DAYS; 天
TimeUnit.HOURS; 小时
TimeUnit.MINUTES; 分钟
TimeUnit.SECONDS; 秒
TimeUnit.MILLISECONDS; 毫秒
TimeUnit.MICROSECONDS; 微秒
TimeUnit.NANOSECONDS; 纳秒
能简单说一下参数之间的关系吗?
任务优先使用核心线程执行,满了进入等待队列,队列满了启用非核心线程备用,线程池达到最大线程数量后触发拒绝策略,非核心线程的空闲时间超过存活时间就被回收。
核心线程数不够会怎么进行处理?
- 当提交的任务数超过了 corePoolSize,但是小于 maximumPoolSize 时,线程池会创建新的线程来处理任务。
- 当提交的任务数超过了 maximumPoolSize 时,线程池会根据拒绝策略来处理任务。

浙公网安备 33010602011771号