目录
ThreadPoolExecutor
为什么用线程池
/**
* 传统多线程代码编写方式
*/
class MyTask implements Runnable{
public void run(){}
}
public class Test{
public static void main(String[] args){
MyTask task = new MyTask();
Thread thread = new Thread(task);
thread.start();
}
}
传统的方式编写多线程:
1:新建线程,用来执行任务,任务执行完毕后,线程被销毁。线程的频繁新建/销毁都是由JVM管理的,非常的消耗系统性能。
2:当任务比较小时,花在创建和销毁线程上的时间会比任务真正执行的时间还长。尤其是如果有大量的任务时,线程的大量创建和销毁,有内存溢出的风险。
线程池的方式编写多线程:
线程池的出现,不但解决了以上两个毛病,同时还带来其它方面的优化和提升:
A:线程池中的线程是可以重用的,不用频繁的创建和销毁,提高了系统的性能。
B:线程池中的队列可以管理大量的任务,任务的执行,调度,排队,丢弃等事宜都由线程池来管理,做到任务可控。
C:线程池对线程进行一些维护和管理,比如线程定时执行,线程生命周期管理,多少个线程并发,线程执行的监控等。
线程池简介
接口 | Executor | 其内仅有execute(Runnable task);方法 |
ExecutorService | 继承Executor,对线程有更多的管理,常用的有:submit()方法、shutdown()方法等 | |
ScheduledExecutorService | 继承ExecutorService,对线程又进一步的支持了定时执行的职能 | |
类 | AbstractExecutorService | 默认实现了ExecutorService接口中的部分方法 |
ThreadPoolExecutor | 我们常用的类,里面的职能有:维护任务队列,维护线程组,管理线程调度,执行,监控,等 | |
ScheduledThreadPoolExecutor | 里面的职能相对于父类ThreadPoolExecutor来说,多了对线程定时执行的职能 |
线程池只是并发编程中的一小部分,下图是史上最全面的Java的并发编程学习技术总汇
线程池工作原理
/**
* 线程池的构造函数
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) //后两个参数为可选参数
线程池的构造函数:
谈到线程池的工作原理,首先要从线程池的构造函数说起:
参数名 | 中文名称 | 业务说明(我以"快递员派送包裹"来易于大家理解) |
corePoolSize | 核心线程数 | 有编制的正式快递员员工个数 |
maximumPoolSize | 最大线程数 | 比如:双11了,包裹量急剧增多,正式员工忙不过来,只能新招临时工 =( 最大 - 核心 ) |
keepAliveTime | 临时工呆多久 | 临时工就是临时工(包裹量不多的时候会被辞退的),能呆几天呢,就是这个keepAliveTime |
unit | 临时工呆多久的计量单位 | 比如:临时工呆多少小时,那么unit就计量单位为小时;临时工能呆多少天,unit计量单位就是天;临时工能呆多少月,unit计量单位就是月....等等 |
workQueue | 任务队列 | 需要派送的大量包裹存储的地方 |
threadFactory | 线程工厂 | 使用ThreadFactory创建新线程,默认使用defaultThreadFactory创建线程 |
handle | 异常处理 | 包裹实在太多,多到正式员工和临时工一起派送都忙不过来,另外存放包裹的地方都被撑爆了,实在没地方存这些包裹了。那么这时仍源源不断新来的包裹我们的处理方案就是handle |
线程池工作原理描述:
1:有新任务了,尽可能的让核心线程去执行;
2:核心线程都在忙了,在来的任务就放到队列中去排队等待被调度;
3:队列中都塞满了任务,还来新任务,就临时招募非核心线程来执行刚到的新任务;
4:队列满了,核心线程/非核心线程都在忙,还来新任务,那么只能启用安全策略;
5:安全策略来处理仍源源不断到来的新任务,安全策略决定是丢弃新来的任务,还是其它处理。
线程池工作原理图解:
线程池工作原理的流程图:
上述图解动画,翻译成程序的流程图如下: