@Configuration @EnableAsync public class ThreadAsyncConfigurer implements AsyncConfigurer { private final static Logger log = LoggerFactory.getLogger(ThreadAsyncConfigurer.class); @Bean @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor(); // 设置核心线程数 threadPool.setCorePoolSize(Runtime.getRuntime().availableProcessors()); // 设置最大线程数 threadPool.setMaxPoolSize(Runtime.getRuntime().availableProcessors() * 100); // 线程池所使用的缓冲队列 threadPool.setQueueCapacity(0); // 等待任务在关机时完成--表明等待所有线程执行完 threadPool.setWaitForTasksToCompleteOnShutdown(true); // 等待时间 (默认为0,此时立即停止),并没等待xx秒后强制停止 threadPool.setAwaitTerminationSeconds(60); // 设置线程名前缀 threadPool.setThreadNamePrefix("AsyncExecutor-"); // 设置拒绝策略 threadPool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 初始化线程 threadPool.initialize(); return threadPool; } /** * 异常处理 * * @return */ @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new CustomAsyncExceptionHandler(); } /** * 自定义异常处理类 */ class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler { @Override public void handleUncaughtException(Throwable throwable, Method method, Object... obj) { log.error("==========================" + throwable.getMessage() + "=======================", throwable); log.error("exception method:" + method.getName()); for (Object param : obj) { log.error("Parameter value - " + param); } } } }
/** * @program: cloud-framework-api * @Description: 自定义线程池 提供JDK自带线程池和spring下的线程池两种线程池供选择使用 * @Author: zwx * @Date: 2021/3/19 13:46 */ @Configuration @EnableAsync public class ThreadTaskConfig { /** * 异步方法调用示例 * @Async("taskExecutor") * public void doTaskOne() throws Exception {} * @Async("myExecutor") * public void doTaskTwo() throws Exception {} */ /** * spring提供的线程池 此处设置成CPU密集型任务 */ @Bean("taskExecutor") public Executor taskExecutor(){ ThreadPoolTaskExecutor poolExecutor = new ThreadPoolTaskExecutor(); //设置核心线程数 如果是CPU密集型任务,最佳线程数为CPU+1 如果是IO密集型任务,最佳线程数为CPU*2 poolExecutor.setCorePoolSize(Runtime.getRuntime().availableProcessors()+1); //设置最大线程数 poolExecutor.setMaxPoolSize(Runtime.getRuntime().availableProcessors() * 100); //允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁 poolExecutor.setKeepAliveSeconds(60); //缓冲队列200:用来缓冲执行任务的队列 poolExecutor.setQueueCapacity(200); // 等待任务在关机时完成--表明等待所有线程执行完 poolExecutor.setWaitForTasksToCompleteOnShutdown(true); // 等待时间 (默认为0,此时立即停止),并没等待60秒后强制停止 poolExecutor.setAwaitTerminationSeconds(60); //线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池 poolExecutor.setThreadNamePrefix("taskExecutor-"); //拒绝策略:这里采用了CallerRunsPolicy策略,当线程池没有处理能力的时候,该策略会直接在 execute 方法的调用线程中运行被拒绝的任务; // 如果执行程序已关闭,则会丢弃该任务 poolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return poolExecutor; } /** * JDK自带线程池 此处设置成IO密集型任务 */ @Bean("myExecutor") public Executor myExecutor(){ //自定义jdk线程池七大核心参数 ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor( Runtime.getRuntime().availableProcessors() * 2, Runtime.getRuntime().availableProcessors() * 100, 120L, //允许线程空闲时间和单位,超过了核心线程出之外的线程在空闲时间到达之后会被销毁 TimeUnit.SECONDS, //指定一种队列 (有界队列 先进先出) new ArrayBlockingQueue<>(100), //默认线程工厂 Executors.defaultThreadFactory(), //自定义拒绝策略 new ThreadPoolExecutor.CallerRunsPolicy() ); return poolExecutor; } /*分析下继承关系: 1、ThreadPoolTaskExecutor extends (2)ExecutorConfigurationSupport implements (3)AsyncListenableTaskExecutor, (4)SchedulingTaskExecutor 2、 ExecutorConfigurationSupport extends CustomizableThreadFactory implements BeanNameAware, InitializingBean, DisposableBean 3、public interface AsyncListenableTaskExecutor extends AsyncTaskExecutor 4、public interface SchedulingTaskExecutor extends AsyncTaskExecutor 从上继承关系可知: ThreadPoolExecutor是一个java类不提供spring生命周期和参数装配。 ThreadPoolTaskExecutor实现了InitializingBean, DisposableBean ,xxaware等,具有spring特性 AsyncListenableTaskExecutor提供了监听任务方法(相当于添加一个任务监听,提交任务完成都会回调该方法) 简单理解: 1、ThreadPoolTaskExecutor使用ThreadPoolExecutor并增强,扩展了更多特性 2、ThreadPoolTaskExecutor只关注自己增强的部分,任务执行还是ThreadPoolExecutor处理。 3、前者spring自己用着爽,后者离开spring我们用ThreadPoolExecutor爽。 注意:ThreadPoolTaskExecutor 不会自动创建ThreadPoolExecutor需要手动调initialize才会创建 如果@Bean 就不需手动,会自动InitializingBean的afterPropertiesSet来调initialize*/ }