为什么需要线程池
一.为什么需要线程池
线程是不是越多越好?
- 线程在java中是一个对象,更是操作系统的资源,线程创建、销毁需要时间。如果创建时间+销毁时间>执行时间就很不合算。
- java对象占用堆内存,操作系统线程系统内存,根据jvm规范,一个线程默认最大栈大小为1M,这个栈空间是需要从系统内存中分配的。线程过多,会消耗很多的内存。
- 操作系统需要频繁切换线程上下文,影响性能。
线程池的推出,就是为了方便的控制线程数量。
二.线程池原理-概念
- 线程池管理器:用于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务;
- 工作线程:线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
- 工作接口:每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务入口,任务执行完成后的收尾工作,任务的执行状态等;
- 任务队列:用于存放没有处理的任务,提供一种缓冲机制;
线程池API-接口定义和实现类
类型 | 名称 | 描述 |
---|---|---|
接口 | Executor | 最上层接口,定义了执行任务的方法execute |
接口 | ExecutorService | 继承了Executor接口,拓展了Callable、Future、关闭方法 |
接口 | ScheduledExecutorService | 继承了ExecutorService,增加了定时任务相关的方法 |
实现类 | ThreadPoolExecutor | 基础标准的线程池实现 |
实现类 | ScheduledThreadPoolExecuto | 继承ThreadPoolExecutor,实现了ScheduledExecutorService中相关定时任务的方法 |
线程池API
线程池原理-任务execute过程
- 是否达到核心线程数量?没达到,创建一个工作线程来执行任务
- 工作队列是否已满?没满,则将新提交的任务存储在工作队列中
- 是否达到线程池最大数量?没达到,则创建一个新的工作线程来执行任务
- 最后,执行拒绝策略来处理这个任务
线程数量
计算型任务:CPU数量的1-2倍
IO型任务:相对比计算型任务,需要多一些线程,要根据具体的io阻塞时长进行考量决定。
如tomcat中默认的最大线程数为:200