SpringBoot如何实现并发任务并返回结果
作者:倔强100%
SpringBoot并发任务并返回结果
并发的实现以及结果获取
并发即多个线程同时进行任务,即异步任务,以下例子测试了并发进行四个任务,并同时返回结果的案例。
service层
@Service public class AsyncTest { @Async public Future<Boolean> doReturn1(){ try { // 这个方法需要调用500毫秒 Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0; i < 10; i++) { System.out.println("一号线程:"+i); } // 消息汇总 return new AsyncResult<>(true); } @Async public Future<Boolean> doReturn2(){ try { // 这个方法需要调用500毫秒 Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0; i < 10; i++) { System.out.println("二号线程:"+i); } // 消息汇总 return new AsyncResult<>(true); } @Async public Future<Boolean> doReturn3(){ try { // 这个方法需要调用500毫秒 Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0; i < 10; i++) { System.out.println("三号线程:"+i); } // 消息汇总 return new AsyncResult<>(true); } @Async public Future<Boolean> doReturn4(){ try { // 这个方法需要调用500毫秒 Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0; i < 10; i++) { System.out.println("四号线程:"+i); } // 消息汇总 return new AsyncResult<>(true); } }
controller层
@RequestMapping("/async") public String async(){ List<Future<Boolean>> futures = new ArrayList<>(); Future<Boolean> flag1 = asyncTest.doReturn1(); Future<Boolean> flag2 = asyncTest.doReturn2(); Future<Boolean> flag3 = asyncTest.doReturn3(); Future<Boolean> flag4 = asyncTest.doReturn4(); futures.add(flag1); futures.add(flag2); futures.add(flag3); futures.add(flag4); List<Boolean> response = new ArrayList<>(); for (Future future : futures) { Boolean flag = null; try { flag = (Boolean) future.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } response.add(flag); } System.out.println(response); return response.toString(); }
这种方法即可在并发的时候拦截到全部完成后的结果进行判断,满足才进行下一步。
SpringBoot并发配置
Spring Boot 提供了一些默认的并发配置,可以通过配置文件或代码进行调整。
下面介绍一些常用的 Spring Boot 并发配置:
线程池配置
可以在 application.properties 或 application.yml 文件中配置线程池的参数,例如最大线程数、核心线程数等:
# application.yml spring: task: execution: pool: max-threads: 10 core-threads: 5
异步处理配置
可以通过 @EnableAsync 注解开启异步处理,并且可以配置线程池的参数:
@Configuration @EnableAsync public class AppConfig { @Bean public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(25); return executor; } }
WebMvc 配置
可以通过配置 WebMvcConfigurerAdapter 来配置 Spring Boot 的 MVC 框架的线程池大小和异步处理:
@Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void configureAsyncSupport(final AsyncSupportConfigurer configurer) { configurer.setTaskExecutor(asyncTaskExecutor()); } @Bean public AsyncTaskExecutor asyncTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(50); executor.setQueueCapacity(100); executor.setThreadNamePrefix("MySpringAsyncThread-"); executor.initialize(); return executor; } }
Tomcat 连接器配置
Tomcat 是 Spring Boot 的默认 Web 服务器,可以通过配置 Tomcat 的连接器参数来进行并发调优:
server: tomcat: max-connections:2000 max-threads:200 min-spare-threads:10 accept-count:100
undertow 配置
如果springboot 配置undertow作为web服务器 则可通过如下参数进行并发调优
# undertow 配置 undertow: # HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的 max-http-post-size: -1 # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理 # 每块buffer的空间大小,越小的空间被利用越充分 buffer-size: 512 # 是否分配的直接内存 direct-buffers: true threads: # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程 io: 8 # 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载 worker: 256
其中 max-connections 表示最大连接数,max-threads 表示最大线程数,min-spare-threads 表示最小空闲线程数,accept-count 表示请求等待队列的大小。
综上所述,可以通过线程池配置、异步处理配置、WebMvc 配置以及 Tomcat 连接器配置来调整 Spring Boot 应用的并发性能和并发能力。在实际应用中,需要结合具体的业务场景和系统架构来进行配置和优化。
通常需要考虑硬件性能、IO模型、网络、压测、服务器监控的实际数据。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。