ThreadPoolTaskExecutor 如果线程池默认的queue满了,会触发什么异常

Spring 中,使用 ThreadPoolTaskExecutor 时,如果线程池中的 任务队列(Queue) 满了,默认情况下并不会直接抛出异常,而是会根据 RejectedExecutionHandler 的策略来决定如何处理被拒绝的任务。ThreadPoolTaskExecutor 继承自 Java 的 ThreadPoolExecutor,因此它使用了 ThreadPoolExecutor 中定义的拒绝策略来处理这种情况。

RejectedExecutionHandler 的默认策略

ThreadPoolTaskExecutor 使用的底层实现是 ThreadPoolExecutor,它有四种处理拒绝任务的策略,默认情况下使用的是 AbortPolicy。当任务队列满时,会触发 java.util.concurrent.RejectedExecutionException 异常。以下是 ThreadPoolExecutor 支持的四种策略:

  1. AbortPolicy(默认):当任务无法被提交到线程池时,会抛出 RejectedExecutionException
  2. CallerRunsPolicy:当任务无法被提交时,调用该任务的线程(提交任务的线程)会直接运行这个任务。这可能会影响应用程序的性能,因为原本用于提交任务的线程现在正在执行任务。
  3. DiscardPolicy:直接丢弃新提交的任务,不抛出异常。
  4. DiscardOldestPolicy:丢弃队列中最早提交但尚未被执行的任务,然后重新尝试提交当前任务。

默认的处理行为

如果 ThreadPoolTaskExecutor 没有设置自定义的拒绝策略,默认会使用 AbortPolicy,也就是说,当任务队列满了之后,会抛出 RejectedExecutionException。这个异常表明线程池已经无法再接受新的任务,因为工作线程都已占用且队列已满。

自定义拒绝策略

如果不想让任务在队列满的时候直接抛出异常,您可以自定义 ThreadPoolTaskExecutor 的拒绝策略。可以通过 setRejectedExecutionHandler() 方法来指定不同的策略。

例如:

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();

这段代码将 CallerRunsPolicy 设置为拒绝策略,当队列满时,提交任务的线程会执行该任务而不是抛出异常。

结论

ThreadPoolTaskExecutor 中,如果线程池的任务队列满了,默认情况下会抛出 RejectedExecutionException,这是由于使用了默认的 AbortPolicy。您可以根据需要自定义拒绝策略以避免异常或选择其他处理方式。

posted @ 2024-10-10 02:03  gongchengship  阅读(22)  评论(0编辑  收藏  举报