/**
* @author kz 单例模式 IoDh实现,静态内部类
* @date 2022/10/12
*/
public class ThreadPoolSingle {
private ThreadPoolExecutor executor;
//1.私有化构造器
private ThreadPoolSingle(){
executor=new ThreadPoolExecutor(8,20,10, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10), Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
}
//2.静态内部类
public static class ThreadInner{
//3.完成当前对象的实例化
private static final ThreadPoolSingle poolSingle=new ThreadPoolSingle();
}
//4.提供公有方法,外键获取对象
public static ThreadPoolSingle getInstance(){
return ThreadInner.poolSingle;
}
}
1.核心线程数,最小线程数
2.最大线程数,线程池最多可以创建的线程数量
3.线程的空闲时间(回收线程)
4.空闲时间的单位
5.阻塞队列,如果当前任务超过核心线程数,就会放到阻塞队列中
6.线程工厂,创建线程
7.拒绝策略,如果当前线程池 数量已达上线,就会触发拒绝策略
excel导入导出
下载
发送短信也可以用多线程
失败就重试
当创建线程池得时候就已经存在了核心线程?
1.当有任务进来得时候,就会先走核心线程,如果任务超过核心线程得数量
2.就会存到阻塞队列中(先进先出),如果任务过多,超出阻塞队列的最大容量
3.阻塞队列容量已满,线程池验证当前线程是否达到最大限制,如果没有就创建线程,处理新的任务,不是处理阻塞队列得任务.相当于插队
4.当阻塞队列已满并且线程池已达最大线程数得时候(阻塞队列+最大线程数(包含核心线程))新的任务会触发拒绝策略
5.当任务处理完毕得时候,在设置得回收时间内,没有用到除核心线程以外,已经被创建得线程,就会对改线程进行回收。
任务队列是基于阻塞队列实现的,即采用生产者消费者模式,在 Java 中需要实现 BlockingQueue 接口。但 Java 已经为我们提供了 7 种阻塞队列的实现:
注意有界队列和无界队列的区别:如果使用有界队列,当队列饱和时并超过最大线程数时就会执行拒绝策略;而如果使用无界队列,任务队列永远都可以添加任务,所以设置 maximumPoolSize 没有任何意义
ThreadPoolExecutor.AbortPolicy: 中止策略 当线程数量大于最大线程时 ,丢弃任务并抛出RejectedExecutionException异常
ThreadPoolExecutor.DiscardPolicy: 丢弃策略 线程数量大于最大线程时 ,丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy: 丢弃最老任务 丢弃队列最前面的任务,重新提交被拒绝的任务
ThreadPoolExecutor.CallerRunsPolicy: 优先处理策略 由调用线程(提交任务的线程)处理该任务
线程池的默认拒绝策略为AbortPolicy 中止策略
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
如果是比较关键的业务,推荐使用此拒绝策略,这样在系统不能承载更大的并发量的时候,能够及时的通过异常发现。
使用此策略,可能会使我们无法发现系统的异常状态。建议是一些无关紧要的业务采用此策略。
此拒绝策略,是一种喜新厌旧的拒绝策略。是否要采用此种拒绝策略,还得根据实际业务是否允许丢弃老任务来认真衡量
由调用线程处理该任务
线程池的5种状态:Running、ShutDown、Stop、Tidying、Terminated
状态说明:在RUNNING状态下,线程池可以接收新的任务和执行已添加的任务。
线程池的初始化状态是RUNNING。换句话说,线程池被一旦被创建(比如调Executors.newFixedThreadPool()或者使用ThreadPoolExecutor进行创建),就处于RUNNING状态,并且线程池中的任务数为0!线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行处理
状态说明:线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务
当一个线程池调用shutdown()方法时,线程池由RUNNING -> SHUTDOWN
状态说明:线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在执行的任务
调用线程池的shutdownNow()方法的时候,线程池由(RUNNING或者SHUTDOWN ) -> STOP
状态说明:当所有的任务已终止,记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。
若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重写terminated()函数来实现。 当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。 当线程池在STOP状态下,线程池中执行的任务为空时,会由STOP -> TIDYING
状态说明:当钩子函数terminated()被执行完成之后,线程池彻底终止,就变成TERMINATED状态。
线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED
//回收核心线程
executor.allowCoreThreadTimeOut(true);