根据不同的场景,可以选择不同的拒绝策略,如果任务非常重要,线程池队列满了,可以交由调用者线程同步处理.
如果是一些不太重要日志,可以直接丢弃掉.
如果一些可以丢弃,但是又需要知道被丢弃了,可以使用ThreadPoolExecutor.AbortPolicy(),在异常处理中记录日志
/** * laizhenwei 2018-1-1 12:46:02 */ @Configuration @EnableAsync public class ExecutorConfig implements AsyncConfigurer { /** * 替换默认线程池,线程队列满了以后交给调用者执行,也就是同步执行 * @return */ @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(7); executor.setMaxPoolSize(42); executor.setQueueCapacity(11); executor.setThreadNamePrefix("Executor-"); executor.setAllowCoreThreadTimeOut(false); executor.setRejectedExecutionHandler( new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } /** * 队列满了以后,抛弃任务,但是会抛出 rejectedExecution 如果不处理会中断线程 * @return */ @Bean public Executor myExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(1); executor.setMaxPoolSize(2); executor.setQueueCapacity(20); executor.setThreadNamePrefix("MyExecutor-"); executor.setAllowCoreThreadTimeOut(false); executor.setRejectedExecutionHandler( new ThreadPoolExecutor.AbortPolicy()); executor.initialize(); return executor; } /** * 队列满了,直接丢弃当前任务,不抛出异常 * @return */ @Bean public Executor myExecutor1() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(1); executor.setMaxPoolSize(2); executor.setQueueCapacity(20); executor.setThreadNamePrefix("MyExecutor1-"); executor.setAllowCoreThreadTimeOut(false); executor.setRejectedExecutionHandler( new ThreadPoolExecutor.DiscardPolicy()); executor.initialize(); return executor; } /** * 队列满了,丢弃最老的任务,不抛出异常 * @return */ @Bean public Executor myExecutor2() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(1); executor.setMaxPoolSize(2); executor.setQueueCapacity(20); executor.setThreadNamePrefix("MyExecutor2-"); executor.setAllowCoreThreadTimeOut(false); executor.setRejectedExecutionHandler( new ThreadPoolExecutor.DiscardOldestPolicy()); executor.initialize(); return executor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new MyAsyncUncaughtExceptionHandler(); } public static class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler{ @Override public void handleUncaughtException(Throwable throwable, Method method, Object... objects) { System.out.println(throwable.getMessage()); } } }
调用方式使用 value 是bean 的名称
@Async("myExecutor")
如果异步处理的方法,涉及到jdbc事务,那么请先理解Spring事务的连接是保存在ThreadLocal中的原理,避免踩坑.