✅线程池的拒绝策略有哪些?

典型回答

在Java中,线程池的拒绝策略决定了在任务队列已满的情况下,如何处理新提交的任务。当线程池达到最大容量,并且任务队列也已满时,拒绝策略就会起作用。Java提供了四种内置的拒绝策略,它们分别是:

  • AbortPolicy - 这是默认的拒绝策略,当线程池无法接受新任务时,会抛出RejectedExecutionException异常。这意味着新任务会被立即拒绝,不会加入到任务队列中,也不会执行。通常情况下都是使用这种拒绝策略。
  • DiscardPolicy - 这个策略在任务队列已满时,会丢弃新的任务而且不会抛出异常。新任务提交后会被默默地丢弃,不会有任何提示或执行。这个策略一般用于日志记录、统计等不是非常关键的任务。
  • DiscardOldestPolicy - 这个策略也会丢弃任务,但它会先尝试将任务队列中最早的任务删除,然后再尝试提交新任务。如果任务队列已满,且线程池中的线程都在工作,可能会导致一些任务被丢弃。这个策略对于一些实时性要求较高的场景比较合适。
  • CallerRunsPolicy - 这个策略将任务回退给调用线程,而不会抛出异常。调用线程会尝试执行任务。这个策略可以降低任务提交速度,适用于任务提交者能够承受任务执行的压力,但希望有一种缓冲机制的情况。
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    10, // corePoolSize
    10, // maximumPoolSize
    0L, // keepAliveTime
    TimeUnit.MILLISECONDS, // timeUnit
    new LinkedBlockingQueue<>(10), 
    new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);

一般来说,默认的拒绝策略还是比较常用的,因为大多数情况下我们不太会让任务多到线程池中放不下,要不然就提升执行速度,要不然就提升队列长度了。

需要拒绝的情况一般是特殊情况比较多,所以在实际工作中基本就是拒绝并抛异常的方式比较多。

原文: https://www.yuque.com/hollis666/xkm7k3/gfoppg6a3stefkig