• 【线程池】概述及创建


    线程池

    1.什么是线程池?

    线程池就是一个可以复用线程的技术

    2.不使用线程池的问题

    用户每发起一个请求,后台就需要一个新的线程来处理,下次新的任务来了肯定又要创建新线程处理的,而创建新线程的开销是很大的,并且请求过多时,肯定会产生大量的线程出来,这样会严重影响系统的性能

    3.创建线程池

    (1)JDK5.0起提供了代表线程池的接口:ExecutorService

    (2)得到线程池对象

    • 方式一:使用ExecutorService的实现类ThreadPoolExecutor创建一个线程池对象

      ①ThreadPoolExecutor构造器:

      public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
      BlockingQueue< Runnable> workQueue, ThreadFactory threadFactory,
      RejectedExecutionHandler handler)

      • 参数一:corePoolSize : 指定线程池的核心线程的数量
      • 参数二:lmaximumPoolSize:指定线程池的最大线程数量
      • 参数三:keepAliveTime :指定临时线程的存活时间
      • 参数四:unit:指定临时线程存活的时间单位(秒、分、时、天)
      • 参数五:workQueue:指定线程池的任务队列
      • 参数六:threadFactory:指定线程池的线程工厂
      • 参数七:handler:指定线程池的任务拒绝策略(线程都在忙,任务队列也满了的时候,新任务来了该怎么处理

      ②线程池的注意事项

      临时线程什么时候创建:新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程

      什么时候会开始拒绝新任务:核心线程和临时线程都在忙,任务队列也满了,已经达到最大线程数量,新的任务过来的时候才会开始拒绝任务

      public class Demo {
          public static void main(String[] args) {
              ThreadPoolExecutor pool = new ThreadPoolExecutor(
                      3, //核心线程数量
                      5, //最大线程数量
                      30, //临时线程存活时间
                      TimeUnit.SECONDS, //时间单位
                      new ArrayBlockingQueue<>(4), //任务队列
                      Executors.defaultThreadFactory(), //线程工厂
                      new ThreadPoolExecutor.AbortPolicy() //默认拒绝策略(拒绝服务,并且抛出异常)
              );
          }
      }
      /*线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险
      Executors返回的线程池对象的弊端如下
          FixedThreadPool、SingleThreadExecutor任务队列太长(Integer.MAX_VALUE)可能堆积大量请求,导致OOM
          CachedThreadPool、ScheduledThreadPool最大线程数量太大(Integer.MAX_VALUE)可能堆积大量请求,导致OOM*/
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

      ③新任务拒绝策略

      策略详解
      ThreadPoolExecutor.AbortPolicy丢弃任务并抛出RejectedExecutionException异常。是默认的策略
      ThreadPoolExecutor.DiscardPolicy丢弃任务,但是不抛出异常 这是不推荐的做法
      ThreadPoolExecutor.DiscardOldestPolicy抛弃队列中等待最久的任务 然后把当前任务加入队列中
      ThreadPoolExecutor.CallerRunsPolicy由主线程负责调用任务的run()方法从而绕过线程池直接执行
    • 方式二:使用Executors(线程池工具类)调用方法返回不同特点的线程池对象

      方法名称说明
      public static ExecutorService newFixedThreadPool(int nThreads)创建固定线程数量的线程池,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程替代它。
      public static ExecutorService newSingleThreadExecutor()创建只有一个线程的线程池对象,如果该线程出现异常而结束,那么线程池会补充一个新线程。
      public static ExecutorService newCachedThreadPool()线程数量随着任务增加而增加,如果线程任务执行完毕且空闲了60s则会被回收掉。
      public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)创建一个线程池,可以实现在给定的延迟后运行任务,或者定期执行任务。

      注意:线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式更加明确线程池的运行规则,规避资源耗尽的风险。Executors返回的线程池对象的弊端如下
      FixedThreadPool、SingleThreadExecutor任务队列太长(Integer.MAX_VALUE)可能堆积大量请求,导致OOM(内存溢出)
      CachedThreadPool、ScheduledThreadPool最大线程数量太大(Integer.MAX_VALUE)可能堆积大量请求,导致OOM

  • 相关阅读:
    【计算机视觉 | 图像分割】arxiv 计算机视觉关于图像分割的学术速递(8 月 29 日论文合集)
    Springboot毕设项目供应链平台网站1f0ei(java+VUE+Mybatis+Maven+Mysql)
    超级实用的程序员接单平台,看完少走几年弯路,强推第一个!
    Java毕业设计之springboot实现疫情防控核酸检测管理系统
    Kubernetes 网络排查方法
    scrapy+scrapyd+gerapy 爬虫调度框架
    Linux下启动jar包的几种常见方式
    淘宝/天猫API:item_search_similar-搜索相似的商品
    掘金拉美,大有可为,2023美客多官方招商会-深圳站成功举办!
    特征缩放是强制性的吗? 什么时候使用标准化? 什么时候使用归一化?数据的分布会发生什么变化?对异常值有什么影响?模型的准确性会提高吗?
  • 原文地址:https://blog.csdn.net/m0_65462447/article/details/132742211