java.util.concurrent 原生线程池实现的构造参数定义

257 阅读2分钟
  • 为什么要使用线程池?
  1. 因为新线程的创建和销毁 对于CPU来说,存在性能开销的问题。使用线程池可以减少这一部分开销,为服务器提升性能。
  2. 对活动线程的管理。活动线程也会消耗系统资源,如果 JVM 中创建了太多的线程,可能会使系统的内存不足 或 “切换过度” 导致系统资源不足,使用线程池可以限制 请求的数量 等信息,提供了一种 “池化技术” 的来管理线程的能力。
  • 线程池的使用场景
  1. 单个任务处理的时间比较短
  2. 需要处理的任务数量大
  • [强制]线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的的处理可以让程序员本身更加明确线程池的运行规则,规避资源耗尽的风险。

使用JDK本身自带的四种线程池来实现的弊端是什么呢?

  1. newFixedThreadPoolnewSingleThreadExecutor
    • 允许请求的队列长度Integer.MAX_VALUE,这样可能会堆积大量的请求,从而导致 OOM。
  2. newCachedThreadPoolnewScheduledThreadPool
    • 允许的创建线程数量Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。

自定义线程池的实现及参数

ThreadPoolExecutor executor = new ThreadPoolExecutor( 5,     //  最少线程数(core:核心)
                                                      5,     //  最大线程数
                                                      5,     //  线程空闲时长
                                       TimeUnit.SECONDS,     //  线程空闲的时间单位
                                                   null,     //  线程工作队列
                       Executors.defaultThreadFactory(),     //  线程工厂
                  new ThreadPoolExecutor.AbortPolicy());     //  拒绝执行线程任务时的策略

线程池在使用完毕之后,需要 shutdown() 进行平滑关闭(如果还有未执行完的任务,就等待它们执行完)。

  • 添加任务到线程池 使用execute(Runnable) 方法将线程添加到线程池,Runnable 被称为任务,任务执行的方法就是 Runable 类型对象的run()方法。

  • 任务线程的执行优先级

  1. 如果此时线程池中的数量小于 corePoolSize即使线程池中的线程都处于空闲状态,也要创建的新的线程来处理被添加的任务。
  2. 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列workQueue未满,那么任务被放入缓冲队列
  3. 如果此时线程池中的数量大于 corePoolSize缓冲队列 workQueue 已满,并且线程池中的数量小于 maxmumPoolSize创建新的线程来处理被添加的任务。
  4. 如果此时线程池中的数量大于 corePoolSize缓冲队列 workQueue 已满,并且线程池中的数量等于 maxmumPoolSize,那么通过hander所指定的策略来处理此任务。

corePoolSize > workQueue > maximumPoolSize

如果三者都满了,使用handler配置的策略处理被拒绝的任务。

workQueue常用的是:java.util.concurrent.ArrayBlockingQueue

handler有四种配置策略:

  1. ThreadPoolExecutor.AbortPolicy()
    • 抛出java.util.concurrent.RejectedExecutionException异常
  2. ThreadPoolExecutor.CallerRunsPolicy()
    • 重试添加当前的任务,他会自动重复调用execute()方法
  3. ThreadPoolExecutor.DiscardOldestPolicy()
    • 抛弃旧的任务
  4. ThreadPoolExecutor.DiscardPolicy()
    • 抛弃当前的任务