文章目录
一.什么是线程池
当频繁创建销毁线程时会产生损耗,而线程池可以解决这一问题,需要线程时不用在系统中创建,直接从线程池中取;当不需要线程时不用将线程释放,将线程放入线程池中即可.
二.线程池工作原理
|
线程池工作流程:
1.当前线程数小于核心线程数时,创建核心线程.
2.达到核心线程数时,不会立即创建临时线程,而是将任务放到工作队列中.
3.工作队列满了,且当前线程数未达到最大线程数,继续创建临时线程.
4.工作队列满了,且当前线程数达到最大线程数,执行拒绝策略.
5.线程数大于核心线程数,且超过空闲时间时,销毁部分线程,直到当前线程数等于核心线程数.
三.线程池核心参数及参数配置
1.核心参数
-
corePoolSize(核心线程数)
常备线程数,用来处理任务 -
maximumPoolSize(最大线程数)
常备线程数,临时线程数和的最大值.任务太多,常备线程数和工作队列已满时,就会创建临时线程 -
keepAliveTime(临时线程允许的空闲时间)
临时线程处理完任务时,当超过临时线程允许的空闲时间时,就会回收销毁该临时线程.
-
Unit(时间单位)
时间单位,s,ms等
-
workQueue(工作队列)
即传递任务的阻塞队列.核心线程数达到最大时,若此时仍有任务进来,可先将任务添加到工作队列中.
-
RejectExecutionHandler(拒绝策略)
当前线程超过线程池最大线程数后的处理策略AbortPolicy():超过负荷,直接抛出异常(默认策略).
CallerRunsPolicy():调用者负责处理.
DiscardOldestPolicy():丢弃队列中最早的任务,将新任务加入.
DiscardPolicy():丢弃新来的任务. -
ThreadFactory(线程工厂)
创建线程的工厂类
2.参数配置
线程池配置数量须根据实际情况决定,如业务类型,CPU,IO,等.
2.1 CPU密集型
线程数=CPU的核数+1
2.2 IO密集型
线程数=CPU的核数*(1+CPU等待时间/CPU执行时间)
四.如何创建并实现一个线程池
1.Executors工具类创建线程池
-
newFixedThreadPool
创建固定线程数的线程数,核心线程数=最大线程数 -
newCachedThreadPool
创建线程数目动态增长的线程池(可扩容),核心线程数=0 -
newSingleThreadPool
创建只包含单个线程的线程池,核心线程数=最大线程数=1 -
newScheduledThreadPool
创建一个支持定时及周期性的任务执行的线程池,大多数情况下可以替代Timber
2.线程池的提交方式
-
submit():用于提交一个需要返回结果的任务
-
execute():用于提交不需要返回结果的任务
五.其他
-
Executor和ExecutorService的区别与联系:
ExecutorService接口继承了 Executor接口,是Executor的子接口
Executor中的execute()方法用来接受Runnable接口的对象,不返回任何结果;
ExecutorService中的submit()方法接受Runnable和Callable接口的对象,通过Furture对象返回结果 -
Executors类提供工厂方法来创建不同类型的线程池
-
ThreadPoolExecutor可以创建自定义线程池