ThreadPoolTaskExecutor 如果线程池默认的queue满了,会触发什么异常
在 Spring 中,使用 ThreadPoolTaskExecutor
时,如果线程池中的 任务队列(Queue) 满了,默认情况下并不会直接抛出异常,而是会根据 RejectedExecutionHandler
的策略来决定如何处理被拒绝的任务。ThreadPoolTaskExecutor
继承自 Java 的 ThreadPoolExecutor
,因此它使用了 ThreadPoolExecutor
中定义的拒绝策略来处理这种情况。
RejectedExecutionHandler
的默认策略
ThreadPoolTaskExecutor
使用的底层实现是 ThreadPoolExecutor
,它有四种处理拒绝任务的策略,默认情况下使用的是 AbortPolicy
。当任务队列满时,会触发 java.util.concurrent.RejectedExecutionException
异常。以下是 ThreadPoolExecutor
支持的四种策略:
- AbortPolicy(默认):当任务无法被提交到线程池时,会抛出
RejectedExecutionException
。 - CallerRunsPolicy:当任务无法被提交时,调用该任务的线程(提交任务的线程)会直接运行这个任务。这可能会影响应用程序的性能,因为原本用于提交任务的线程现在正在执行任务。
- DiscardPolicy:直接丢弃新提交的任务,不抛出异常。
- DiscardOldestPolicy:丢弃队列中最早提交但尚未被执行的任务,然后重新尝试提交当前任务。
默认的处理行为
如果 ThreadPoolTaskExecutor
没有设置自定义的拒绝策略,默认会使用 AbortPolicy
,也就是说,当任务队列满了之后,会抛出 RejectedExecutionException
。这个异常表明线程池已经无法再接受新的任务,因为工作线程都已占用且队列已满。
自定义拒绝策略
如果不想让任务在队列满的时候直接抛出异常,您可以自定义 ThreadPoolTaskExecutor
的拒绝策略。可以通过 setRejectedExecutionHandler()
方法来指定不同的策略。
例如:
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
这段代码将 CallerRunsPolicy
设置为拒绝策略,当队列满时,提交任务的线程会执行该任务而不是抛出异常。
结论
在 ThreadPoolTaskExecutor
中,如果线程池的任务队列满了,默认情况下会抛出 RejectedExecutionException
,这是由于使用了默认的 AbortPolicy
。您可以根据需要自定义拒绝策略以避免异常或选择其他处理方式。