前言:
现在同学们对“spring异步实现”大约比较关怀,我们都想要剖析一些“spring异步实现”的相关内容。那么小编同时在网摘上收集了一些关于“spring异步实现””的相关文章,希望你们能喜欢,小伙伴们快快来了解一下吧!在项目的开发中,异步任务是非常重要的一个点,在我们程序对一些处理较慢的情况,可以使用异步任务,直接响应前端结果,再异步处理任务。这也是提高用户体验的地方,不然会有可能用户需要等待很久。
一、模拟同步任务处理复杂逻辑
在Service里通过线程休眠3s的方式模拟处理复杂的任务
然后在Controller中调用这个服务,之后返回前端ok
在前端调用的时候就会一直处于加载状态,3s后才会返回响应的结果,这就是同步任务,我们想要先返回ok,然后Service的处理逻辑异步去执行。
二、异步任务的使用1. 在启动类中加入@EnableAsync注解,表明开启异步功能
java复制代码import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication@EnableAsync // 开启异步功能public class MySpringBootApplication { public static void main(String[] args) { SpringApplication.run(MySpringBootApplication.class, args); }}2. 在对应的Service方法上添加@Async注解
java复制代码import com.jk.service.AsyncService;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;@Servicepublic class AsyncServiceImpl implements AsyncService { @Override @Async // 设置方法为异步任务 public void test() { try { Thread.sleep(3000); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println("数据处理完毕"); }}
这样就实现了我们异步任务的使用,此时再调用这个接口,就会立即返回ok,然后程序异步去执行数据处理的任务。
在上面这种方法可以实现基本的异步任务,其实本质也是SpringBoot使用线程池的方式去处理任务,对于这个默认线程池的配置,我们可以在application.yml中进行配置
yml复制代码# 线程池配置参数task: pool: corePoolSize: 10 # 设置核心线程数 maxPoolSize: 20 # 设置最大线程数 keepAliveTime: 300 # 设置空闲线程存活时间(秒) queueCapacity: 100 # 设置队列容量 threadNamePrefix: "async-" # 设置线程名称前缀 awaitTerminationSeconds: 60 # 设置线程池等待终止时间(秒)
但是对于我们项目开发中,如果有多个异步任务,每个异步任务需要调度的系统资源不一样,如支付我们可能需要调用较多的系统资源去异步处理,而邮件发送不需要太多的系统资源处理,这时候我们就可以自定义两个线程池来分别去异步处理这两个任务。
三、自定义线程池配置及使用1. 创建自定义线程池配置类
config.AsyncConfig:
java复制代码import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.EnableAsync;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;import java.util.concurrent.ThreadPoolExecutor;@Configuration@EnableAsyncpublic class AsyncConfig { @Bean("asyncExecutor") public Executor asyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 核心线程数 executor.setCorePoolSize(10); // 最大线程数 executor.setMaxPoolSize(20); // 任务队列大小 executor.setQueueCapacity(100); // 线程池名称前缀 executor.setThreadNamePrefix("custom-async-"); // 允许线程的空闲时间 executor.setKeepAliveSeconds(30); /** * 拒绝处理策略 * CallerRunsPolicy():交由调用方线程运行,比如 main 线程。 * AbortPolicy():直接抛出异常。 * DiscardPolicy():直接丢弃。 * DiscardOldestPolicy():丢弃队列中最老的任务。 */ executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 线程初始化 executor.initialize(); return executor; }}
因为@Configuration会自动注入到SpringBoot容器里,所以我们可以把@EnableAsync写在这里不需要再写在启动类上,另外通过@Bean的方式把这个线程池对象注入到容器
2. 在相应的Service方法上通过@Async指定线程池执行
java复制代码import com.jk.service.AsyncService;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;@Servicepublic class AsyncServiceImpl implements AsyncService { @Override @Async("asyncExecutor") // 需要指定自定义线程池的名称 public void test() { try { Thread.sleep(3000); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println("数据处理完毕"); }}
这样就实现了我们自定义线程池执行异步任务,如果需要多个线程池,我们同样可以在线程池配置类中定义多个,如下所示,然后在相应的Service方法上指定线程池名称即可。
这样就实现了在SpringBoot中使用异步任务及配置自定义线程池去执行异步任务,如果大家有什么疑问也可以评论区留言哦,希望大家多多点赞、收藏!
作者:JK凯
链接:
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
标签: #spring异步实现