Java-线程池

线程池


池化思想:线程池、字符串常量池、数据库连接池
线程池优点:
提高线程得利用率
提高程序得响应速度
便于统一管理线程对象
可以控制最大并发数

/**
 * @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;
    }
}

一、线程池7大参数

1.核心线程数,最小线程数
2.最大线程数,线程池最多可以创建的线程数量
3.线程的空闲时间(回收线程)
4.空闲时间的单位
5.阻塞队列,如果当前任务超过核心线程数,就会放到阻塞队列中
6.线程工厂,创建线程
7.拒绝策略,如果当前线程池 数量已达上线,就会触发拒绝策略

excel导入导出
下载
发送短信也可以用多线程
失败就重试

二、线程池的运行过程

当创建线程池得时候就已经存在了核心线程?
1.当有任务进来得时候,就会先走核心线程,如果任务超过核心线程得数量
2.就会存到阻塞队列中(先进先出),如果任务过多,超出阻塞队列的最大容量
3.阻塞队列容量已满,线程池验证当前线程是否达到最大限制,如果没有就创建线程,处理新的任务,不是处理阻塞队列得任务.相当于插队
4.当阻塞队列已满并且线程池已达最大线程数得时候(阻塞队列+最大线程数(包含核心线程))新的任务会触发拒绝策略
5.当任务处理完毕得时候,在设置得回收时间内,没有用到除核心线程以外,已经被创建得线程,就会对改线程进行回收。

三、阻塞队列

任务队列是基于阻塞队列实现的,即采用生产者消费者模式,在 Java 中需要实现 BlockingQueue 接口。但 Java 已经为我们提供了 7 种阻塞队列的实现:

  1. ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列(数组结构可配合指针实现一个环形队列)。
  2. LinkedBlockingQueue: 一个由链表结构组成的有界阻塞队列,在未指明容量时,容量默认为 Integer.MAX_VALUE。
  3. PriorityBlockingQueue: 一个支持优先级排序的无界阻塞队列,对元素没有要求,可以实现 Comparable 接口也可以提供 Comparator 来对队列中的元素进行比较。跟时间没有任何关系,仅仅是按照优先级取任务。
  4. DelayQueue:类似于PriorityBlockingQueue,是二叉堆实现的无界优先级阻塞队列。要求元素都实现 Delayed 接口,通过执行时延从队列中提取任务,时间没到任务取不出来。
  5. SynchronousQueue: 一个不存储元素的阻塞队列,消费者线程调用 take() 方法的时候就会发生阻塞,直到有一个生产者线程生产了一个元素,消费者线程就可以拿到这个元素并返回;生产者线程调用 put() 方法的时候也会发生阻塞,直到有一个消费者线程消费了一个元素,生产者才会返回。
  6. LinkedBlockingDeque: 使用双向队列实现的有界双端阻塞队列。双端意味着可以像普通队列一样 FIFO(先进先出),也可以像栈一样 FILO(先进后出)。
  7. LinkedTransferQueue: 它是ConcurrentLinkedQueue、LinkedBlockingQueue 和 SynchronousQueue 的结合体,但是把它用在 ThreadPoolExecutor 中,和 LinkedBlockingQueue 行为一致,但是是无界的阻塞队列。

注意有界队列和无界队列的区别:如果使用有界队列,当队列饱和时并超过最大线程数时就会执行拒绝策略;而如果使用无界队列,任务队列永远都可以添加任务,所以设置 maximumPoolSize 没有任何意义

四、拒绝策略

ThreadPoolExecutor.AbortPolicy: 中止策略 当线程数量大于最大线程时 ,丢弃任务并抛出RejectedExecutionException异常
ThreadPoolExecutor.DiscardPolicy丢弃策略 线程数量大于最大线程时 ,丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy丢弃最老任务 丢弃队列最前面的任务,重新提交被拒绝的任务
ThreadPoolExecutor.CallerRunsPolicy优先处理策略 由调用线程(提交任务的线程)处理该任务
线程池的默认拒绝策略为AbortPolicy 中止策略
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述

拒绝策略场景分析

4.1AbortPolicy 中止策略

如果是比较关键的业务,推荐使用此拒绝策略,这样在系统不能承载更大的并发量的时候,能够及时的通过异常发现。

4.2 DiscardPolicy 丢弃策略

使用此策略,可能会使我们无法发现系统的异常状态。建议是一些无关紧要的业务采用此策略。

4.3 DiscardOldestPolicy 丢弃最老任务

此拒绝策略,是一种喜新厌旧的拒绝策略。是否要采用此种拒绝策略,还得根据实际业务是否允许丢弃老任务来认真衡量

4.4 CallerRunsPolicy 优先处理策略

由调用线程处理该任务

五、线程池的五大状态

线程池的5种状态:Running、ShutDown、Stop、Tidying、Terminated

5.1 RUNNING

状态说明:在RUNNING状态下,线程池可以接收新的任务和执行已添加的任务。
线程池的初始化状态是RUNNING。换句话说,线程池被一旦被创建(比如调Executors.newFixedThreadPool()或者使用ThreadPoolExecutor进行创建),就处于RUNNING状态,并且线程池中的任务数为0!线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行处理

5.2 SHUTDOWN

状态说明:线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务
当一个线程池调用shutdown()方法时,线程池由RUNNING -> SHUTDOWN

5.3 STOP

状态说明:线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在执行的任务
调用线程池的shutdownNow()方法的时候,线程池由(RUNNING或者SHUTDOWN ) -> STOP

5.3TIDYING

状态说明:当所有的任务已终止,记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。
若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重写terminated()函数来实现。 当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。 当线程池在STOP状态下,线程池中执行的任务为空时,会由STOP -> TIDYING

5.4 TERMINATED

状态说明:当钩子函数terminated()被执行完成之后,线程池彻底终止,就变成TERMINATED状态。
线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED

六、回收核心线程

//回收核心线程
executor.allowCoreThreadTimeOut(true);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kkkouz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值