• Springboot配置异步线程解释


    AsyncConfigurer:部分源码
    
    /**
     * Interface to be implemented by @{@link org.springframework.context.annotation.Configuration
     * Configuration} classes annotated with @{@link EnableAsync} that wish to customize the
    这里注意:人话就是要用Configuration类和EnableAsync}定制化
     */
    public interface AsyncConfigurer {
    
    	/**人话是:执行器实例
    	 */
    	@Nullable
    	default Executor getAsyncExecutor() {
    		return null;
    	}
    
    	/**源码注释自己去看,我这里只说人话:这里是异步时获取异常的
    	 */
    	@Nullable
    	default AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    		return null;
    	}
    
    }
    
    在springboot中使用:
    1,在启动类上添加注解@EnableAsync  
    2.在使用的方法上使用@Async
    3.在需要的类上使用@Async,这时候该类里面的方法都是异步的
    4.@Async的默认线程池为SimpleAsyncTaskExecutor(不推荐使用)。
    5.需要异常时需要手动new一个异常出来
    

     

    @Async默认异步配置使用的是SimpleAsyncTaskExecutor,该线程池默认来一个任务创建一个线程,若系统中不断的创建线程,最终会导致系统占用内存过高,引发OutOfMemoryError错误。
    针对线程创建问题,SimpleAsyncTaskExecutor提供了限流机制,通过concurrencyLimit属性来控制开关,
    当concurrencyLimit>=0时开启限流机制,
    默认关闭限流机制即concurrencyLimit=-1,当关闭情况下,会不断创建新的线程来处理任务。
    基于默认配置,SimpleAsyncTaskExecutor并不是严格意义的线程池,达不到线程复用的功能。
    

    无返回值的调用:
     
    有返回值调用:记得使用Futrue线程,请记住这个有返回但是阻塞future.get会有等待,跟具业务要求合理安排即可
    自定义线程池:
    
    1.重新实现接口AsyncConfigurer;
    
    2.继承AsyncConfigurerSupport;
    
    3.配置由自定义的TaskExecutor替代内置的任务执行器
    /**
     * @auth wangbiao
     * @date 2022 年 08 07 日 14:52
     * @description:实现AsyncConfigurer接口
     */
    @Slf4j
    @EnableAsync
    @Configuration
    public class MyAsyncConfigurer implements AsyncConfigurer {
    
    
        @Override
        public Executor getAsyncExecutor() {
            return executor();
        }
    
    
        @Bean("kingAsyncExecutor")
        public ThreadPoolTaskExecutor executor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            int corePoolSize = 10;
            executor.setCorePoolSize(corePoolSize);
            int maxPoolSize = 50;
            executor.setMaxPoolSize(maxPoolSize);
            int queueCapacity = 10;
            executor.setQueueCapacity(queueCapacity);
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            String threadNamePrefix = "kingDeeAsyncExecutor-";
            executor.setThreadNamePrefix(threadNamePrefix);
            executor.setWaitForTasksToCompleteOnShutdown(true);
            // 使用自定义的跨线程的请求级别线程工厂类19         int awaitTerminationSeconds = 5;
            executor.setAwaitTerminationSeconds(5);
            executor.initialize();
            return executor;
        }
        @Override
        public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
            return (ex, method, params) -> log.info(String.format("执行异步任务'%s'", method), ex);    }
    }
    
    package datachange.mulit.config.config;
    
    import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
    import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
    
    import java.util.concurrent.Executor;
    
    /**
     * @auth wangbiao
     * @date 2022 年 08 07 日 16:15
     * @description: 继承AsyncConfigurerSupport类 ,这种方式和实现AsyncConfigurer接口一样,就不再赘述了
     */
    public class MytAsyncConfigurerSupport  extends AsyncConfigurerSupport {
        public MytAsyncConfigurerSupport() {
            super();
        }
    
        @Override
        public Executor getAsyncExecutor() {
            return super.getAsyncExecutor();
        }
    
        @Override
        public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
            return super.getAsyncUncaughtExceptionHandler();
        }
    }
    
    package datachange.mulit.config.config;
    
    import org.springframework.core.task.TaskExecutor;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
    
    import java.util.concurrent.ThreadPoolExecutor;
    
    /**
     * @auth wangbiao
     * @date 2022 年 08 07 日 16:26
     * @description:自定义TaskExecutor,作为一个普通的javabean使用,
     */
    public class TaskExecutorExample {
    
        public TaskExecutorExample(TaskExecutor taskExecutor) {
            this.taskExecutor = taskExecutor;
        }
    
        private TaskExecutor taskExecutor;
    
    
        public void printMessage() {
            for (int i = 0; i < 25; i++) {
                taskExecutor.execute(new MessageTask("message" + i));
            }
        }
    
        //自己的任务,在实际使用时可以更具业务编写,然后扔到printMessage里面交给执行器taskExecutor即可
        private class MessageTask implements Runnable {
            protected String message;
    
            public MessageTask(String message) {
                this.message = message;
            }
    
            @Override
            public void run() {
                System.out.println(message);
            }
        }
    
        public static void main(String[] args) {
    
            //要自定义一个执行器的示例使用才可以
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            int corePoolSize = 10;
            executor.setCorePoolSize(corePoolSize);
            int maxPoolSize = 50;
            executor.setMaxPoolSize(maxPoolSize);
            int queueCapacity = 10;
            executor.setQueueCapacity(queueCapacity);
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            String threadNamePrefix = "kingDeeAsyncExecutor-";
            executor.setThreadNamePrefix(threadNamePrefix);
            executor.setWaitForTasksToCompleteOnShutdown(true);
            // 使用自定义的跨线程的请求级别线程工厂类19         int awaitTerminationSeconds = 5;
            executor.setAwaitTerminationSeconds(5);
            executor.initialize();
            TaskExecutorExample taskExecutorExample = new TaskExecutorExample(executor);
    
            //调用自己的业务
            taskExecutorExample.printMessage();
    
    
        }
    }
    
  • 相关阅读:
    敏捷社区--干货下载 | 10月携程敏捷总动员沙龙
    敏捷开发--洞察敏捷模型,从PO的角度看敏捷产品管理
    携程PMO--小罗说敏捷之WIP限制在制品
    Jmeter分布式压测配置
    Django安装
    Git安装与配置,以及pycharm提交代码到github
    SVN状态图标不显示的解决办法
    PyCharm专业版激活+破解到期时间2100年
    部署python项目到linux服务器
    python+selenium自动化测试,浏览器最大化报错解决方法
  • 原文地址:https://www.cnblogs.com/wangbiaohistory/p/16559157.html
Copyright © 2020-2023  润新知