SpringBoot如何實現并發(fā)任務并返回結果
SpringBoot并發(fā)任務并返回結果
并發(fā)的實現以及結果獲取
并發(fā)即多個線程同時進行任務,即異步任務,以下例子測試了并發(fā)進行四個任務,并同時返回結果的案例。
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(); ? ? }
這種方法即可在并發(fā)的時候攔截到全部完成后的結果進行判斷,滿足才進行下一步。
SpringBoot并發(fā)配置
Spring Boot 提供了一些默認的并發(fā)配置,可以通過配置文件或代碼進行調整。
下面介紹一些常用的 Spring Boot 并發(fā)配置:
線程池配置
可以在 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 的連接器參數來進行并發(fā)調優(yōu):
server: ? ? tomcat: ? ? ? ? max-connections:2000 ? ? ? ? max-threads:200 ? ? ? ? min-spare-threads:10 ? ? ? ? accept-count:100
undertow 配置
如果springboot 配置undertow作為web服務器 則可通過如下參數進行并發(fā)調優(yōu)
? # undertow 配置 ? undertow: ? ? # HTTP post內容的最大大小。當值為-1時,默認值為大小是無限的 ? ? max-http-post-size: -1 ? ? # 以下的配置會影響buffer,這些buffer會用于服務器連接的IO操作,有點類似netty的池化內存管理 ? ? # 每塊buffer的空間大小,越小的空間被利用越充分 ? ? buffer-size: 512 ? ? # 是否分配的直接內存 ? ? direct-buffers: true ? ? threads: ? ? ? # 設置IO線程數, 它主要執(zhí)行非阻塞的任務,它們會負責多個連接, 默認設置每個CPU核心一個線程 ? ? ? io: 8 ? ? ? # 阻塞任務線程池, 當執(zhí)行類似servlet請求阻塞操作, undertow會從這個線程池中取得線程,它的值設置取決于系統的負載 ? ? ? worker: 256
其中 max-connections 表示最大連接數,max-threads 表示最大線程數,min-spare-threads 表示最小空閑線程數,accept-count 表示請求等待隊列的大小。
綜上所述,可以通過線程池配置、異步處理配置、WebMvc 配置以及 Tomcat 連接器配置來調整 Spring Boot 應用的并發(fā)性能和并發(fā)能力。在實際應用中,需要結合具體的業(yè)務場景和系統架構來進行配置和優(yōu)化。
通常需要考慮硬件性能、IO模型、網絡、壓測、服務器監(jiān)控的實際數據。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
解決Spring?Security升級到5.5.7、5.6.4及以上啟動報錯出現版本不兼容的問題
這篇文章主要介紹了解決Spring?Security升級到5.5.7、5.6.4及以上啟動報錯出現版本不兼容的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08使用?Spring?AI?+?Ollama?構建生成式?AI?應用的方法
通過集成SpringBoot和Ollama,本文詳細介紹了如何構建生成式AI應用,首先,介紹了AI大模型服務的兩種實現方式,選擇使用ollama進行部署,隨后,通過SpringBoot+SpringAI來實現應用構建,本文為開發(fā)者提供了一個實用的指南,幫助他們快速入門生成式AI應用的開發(fā)2024-11-11