Java线程池知识点总结

本文详细阐述了线程池的优势,如降低资源消耗、提高响应速度和可管理性。介绍了线程池的七个关键参数,包括核心线程数、最大线程数、线程空闲时间和阻塞队列策略。还通过代码示例展示了如何自定义线程池和拒绝策略。讨论了四种常见的Java线程池及其适用场景。
摘要由CSDN通过智能技术生成

1、线程池优势:

  1. 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
  2. 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
  3. 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

2、线程池的七个参数:

  1. 核心线程数量——在线程池当中无论空闲多久都不会被删除的线程
  2. 线程池当中最大的线程数量——线程池当中最大能创建的线程数量
  3. 空闲时间(数值)——临时线程(线程池中出核心线程之外的线程)空闲了多久就会被淘汰的时间。
  4. 空闲时间(单位)——临时线程空闲了多久就会被淘汰的时间单位,要用枚举类TimeUnit类作为参数
  5. 阻塞队列——就是创建一个阻塞队列作为参数传入,就是当线程池当中线程数量已经达到了最大线程数量,允许多少个任务排队获取线程,其余的用参数七那个方案来处理。
  6. 线程工程——不是new一个线程,而是传入一个线程工厂(例如:Executors工具类中的defaultThreadFactory方法返回的就是一个线程工厂)
  7. 拒绝策略——当等待队列中也排满时要怎么处理这些任务。

3、拒绝策略

//代码实现
   /**
     * 之前用工具类进行创建,有好多参数不能自己设置
     * 咱直接自己手动创建一个线程池,自己设置参数
     * 参数一:核心线程数量                           不能小于0
     * 参数二:最大线程数                             不能小于0,数值大于等于核心线程数量
     * 参数三:空闲临时线程最大存活时间(数值)           不能小于0
     * 参数四:空闲临时线程最大存活时间(单位)            用TimeUnit这个枚举类表示
     * 参数五:任务队列,也就是一个堵塞队列               不能为null
     * 参数六:创建线程的工厂                            不能为null
     * 参数七:任务的拒绝策略                             不能为null
     */
 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
        3,  // 核心线程数量
        6,              //最大线程数
        60,             //空闲临时线程最大存活时间(数值)
        TimeUnit.SECONDS,//空闲临时线程最大存活时间(单位)
        new ArrayBlockingQueue<>(3),//任务队列,也就是一个堵塞队列,也可以使用LinkedBlockingQueue这个阻塞队列
        Executors.defaultThreadFactory(),//用线程池工具类Executors创建线程的工厂
        new ThreadPoolExecutor.AbortPolicy()//任务的拒绝策略中其中一个,丢弃任务并抛出RejectedExecutionException
    );
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    threadPoolExecutor.submit(loopTread);
    }

上面的代码我们设置最大线程数量为6,而阻塞队列可以排三个,说明当同时有超过9个任务需要执行,第10个线程就会执行拒绝策略,我设置的策略为丢弃任务,并抛出异常RejectedExecutionException。下面有结果就可以证明我们的猜测。

 74行恰好是我们放入线程池中第10个任务,所以第74行抛出了RejectedExecutionException异常。

4、线程池的执行流程

  • 当核心线程满时,再提交队伍就会在阻塞队列中排队
  • 当核心线程满了,阻塞队列中也满了,才会创建临时线程
  • 当核心线程满了,阻塞队列满了,临时线程也满了,会触发任务拒绝策略,也就是参数七

5、四种已实现的线程池

5.1 CachedThreadPool(缓存线程池)
  • 特点:
    • 核心线程数为0,最大线程数为无限大,意味着线程数量可以无限增加。
    • 任务队列使用 SynchronousQueue,这是一个没有存储空间的阻塞队列。
    • 线程空闲时间超过60秒就会被销毁。
  • 适用场景
    • 适用于执行大量短时间的任务,但要注意,如果任务执行时间过长,会导致线程池中的线程数量增加,占用更多内存。
5.2 FixedThreadPool(固定线程池)
  • 特点:
    • 固定大小:线程池中的线程数量不会改变。
    • 使用无界的阻塞队列来存放任务,确保任务按照提交顺序执行。
    • 当需要执行一个任务时,FixedThreadPool会检查是否有空闲线程可用。
    • 如果有,就将任务交给空闲线程执行。
    • 如果没有空闲线程,就会将任务放入任务队列中等待执行。
  • 适用场景:
    • 限制并发线程数的场景,例如服务器资源有限、数据量较小或不可控的情况。
    • 确保任务按照提交的顺序执行。
5.3 ScheduledThreadPool(定时调度线程池)
  •  是一个用于执行定时任务的线程池。
  • 它可以在一定延迟之后执行任务,或者周期性地执行任务。
  • 只执行一次某个任务:在一定延迟之后执行一次指定的任务。
  • 周期性执行某个任务:在一定延迟之后开始周期性地执行任务,执行周期间隔由指定的时间决定

5.4 SingleThreadExecutor(单个线程池)
  • 特点
    • 只有一个核心线程,提交的任务会依次执行,一个一个地排队执行。
    • 线程池中的线程可以被复用,减少了线程创建和销毁的开销。
  • 应用场景
    • 顺序执行任务:需要按照提交顺序执行任务的场景。
    • 避免线程同步问题:它避免了使用 synchronized 来保证线程同步的复杂性。
    • 资源管理:线程池中的线程可以被复用,减少了频繁创建和销毁线程的开销。
  • 22
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

日上三杆快起床

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

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

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

打赏作者

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

抵扣说明:

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

余额充值