美文网首页
spring boot中设置异步请求默认使用的线程池

spring boot中设置异步请求默认使用的线程池

作者: 莫夏_b560 | 来源:发表于2019-06-18 01:08 被阅读0次

    1、自定义异步线程池,如果不自定义则使用自带的线程池
    (不是真正意义上的线程池,不会复用线程)

    @SpringBootApplication
    public class AsyncConfigExample{
        @Bean
        WebMvcConfigurer configurer(){
            return new WebMvcConfigurerAdapter(){
                @Override
                public void configureAsyncSupport (AsyncSupportConfigurer configurer) {
                    ThreadPoolTaskExecutor t = new ThreadPoolTaskExecutor();
                    t.setCorePoolSize(10);
                    t.setMaxPoolSize(100);
                    t.setQueueCapacity(50);
                    t.setAllowCoreThreadTimeOut(true);
                    t.setKeepAliveSeconds(120);
                    t.initialize();
                    configurer.setTaskExecutor(t);
                }
            };
        }
        public static void main (String[] args) {
            SpringApplication.run(AsyncConfigExample.class, args);
        }
    }
    

    2、springboot使用异步注解@Async

    @Component
    public class AsyncExceptionDemo {
        private static final Logger log = LoggerFactory.getLogger(AsyncExceptionDemo.class);
     
        /**
         * 最简单的异步调用,返回值为void
         */
        @Async
        public void asyncInvokeSimplest() {
            log.info("asyncSimplest");
        }
     
        /**
         * 带参数的异步调用 异步方法可以传入参数
         *  对于返回值是void,异常会被AsyncUncaughtExceptionHandler处理掉
         * @param s
         */
        @Async
        public void asyncInvokeWithException(String s) {
            log.info("asyncInvokeWithParameter, parementer={}", s);
            throw new IllegalArgumentException(s);
        }
     
        /**
         * 异常调用返回Future
         *  对于返回值是Future,不会被AsyncUncaughtExceptionHandler处理,需要我们在方法中捕获异常并处理
         *  或者在调用方在调用Futrue.get时捕获异常进行处理
         * 
         * @param i
         * @return
         */
        @Async
        public Future<String> asyncInvokeReturnFuture(int i) {
            log.info("asyncInvokeReturnFuture, parementer={}", i);
            Future<String> future;
            try {
                Thread.sleep(1000 * 1);
                future = new AsyncResult<String>("success:" + i);
                throw new IllegalArgumentException("a");
            } catch (InterruptedException e) {
                future = new AsyncResult<String>("error");
            } catch(IllegalArgumentException e){
                future = new AsyncResult<String>("error-IllegalArgumentException");
            }
            return future;
        }
     
    }
    

    3、实现AsyncConfigurer接口对异常线程池更加细粒度的控制
    a) 创建线程自己的线程池
    b) 对void方法抛出的异常处理的类AsyncUncaughtExceptionHandler

    
    /**
     * 通过实现AsyncConfigurer自定义异常线程池,包含异常处理
     * 
     * @author hry
     *
     */
    @Service
    public class MyAsyncConfigurer implements AsyncConfigurer{
        private static final Logger log = LoggerFactory.getLogger(MyAsyncConfigurer.class);
     
        @Override
        public Executor getAsyncExecutor() {
            ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();  
            threadPool.setCorePoolSize(1);  
            threadPool.setMaxPoolSize(1);  
            threadPool.setWaitForTasksToCompleteOnShutdown(true);  
            threadPool.setAwaitTerminationSeconds(60 * 15);  
            threadPool.setThreadNamePrefix("MyAsync-");
            threadPool.initialize();
            return threadPool;  
        }
     
        @Override
        public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
             return new MyAsyncExceptionHandler();  
        }
     
        /**
         * 自定义异常处理类
         * @author hry
         *
         */
        class MyAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {  
     
            @Override  
            public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {  
                log.info("Exception message - " + throwable.getMessage());  
                log.info("Method name - " + method.getName());  
                for (Object param : obj) {  
                    log.info("Parameter value - " + param);  
                }  
            }  
     
        } 
     
    }
    
    
    @SpringBootApplication
    @EnableAsync // 启动异步调用
    public class AsyncApplicationWithAsyncConfigurer {
        private static final Logger log = LoggerFactory.getLogger(AsyncApplicationWithAsyncConfigurer.class);
     
        public static void main(String[] args) {
            log.info("Start AsyncApplication.. ");
            SpringApplication.run(AsyncApplicationWithAsyncConfigurer.class, args);
        }
     
     
    }
    

    相关文章

      网友评论

          本文标题:spring boot中设置异步请求默认使用的线程池

          本文链接:https://www.haomeiwen.com/subject/vagtqctx.html