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并不是严格意义的线程池,达不到线程复用的功能。
无返回值的调用:
![](https://img2022.cnblogs.com/blog/1501092/202208/1501092-20220807155456271-362674646.png)
有返回值调用:记得使用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(); } }
一点点学习,一丝丝进步。不懈怠,才不会被时代淘汰