SpringBoot中使用多線程的方法示例
Spring是通過任務執行器(TaskExecutor)來實現多線程和并發編程,使用Spring提供的ThreadPoolTaskExecutor來創建一個基于線城池的TaskExecutor。在使用線程池的大多數情況下都是異步非阻塞的。節省更多的時間,提高效率。
工作原理當主線程中調用execute接口提交執行任務時:則執行以下步驟:注意:線程池初始時,是空的。
如果當前線程數<corePoolSize,如果是則創建新的線程執行該任務 如果當前線程數>=corePoolSize,則將任務存入BlockingQueue 如果阻塞隊列已滿,且當前線程數<maximumPoolSize,則新建線程執行該任務。 如果阻塞隊列已滿,且當前線程數>=maximumPoolSize,則拋出異常RejectedExecutionException,告訴調用者無法再接受任務了。在Springboot中對其進行了簡化處理,只需要配置一個類型為java.util.concurrent.TaskExecutor或其子類的bean,并在配置類或直接在程序入口類上聲明注解@EnableAsync,即可可以開啟異步任務。
調用也簡單,在由Spring管理的對象的方法上標注注解@Async,聲明是異步任務,顯式調用即可生效。
二、聲明讓配置類實現AsyncConfigurer接口,并重寫getAsyncExecutor方法,并返回一個ThreasPoolTaskExecutor,就可以獲取一個基于線程池的TaskExecutor使用注解@EnableAsync開啟異步,會自動掃描
@Configuration@EnableAsyncpublic class ThreadConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(15); executor.setQueueCapacity(25); executor.initialize(); return executor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return null; }}三、調用
通過@Async注解表明該方法是異步方法,如果注解在類上,那表明這個類里面的所有方法都是異步的
@Servicepublic class AsyncTaskService { @Async public void executeAsyncTask(int i) { System.out.println('線程' + Thread.currentThread().getName() + ' 執行異步任務:' + i); }}四、進階
有時候我們不止希望異步執行任務,還希望任務執行完成后會有一個返回值,在java中提供了Future泛型接口,用來接收任務執行結果,springboot也提供了此類支持,使用實現了ListenableFuture接口的類如AsyncResult來作為返回值的載體。比如上例中,我們希望返回一個類型為String類型的值,可以將返回值改造為:
@Async public Future<String> executeAsyncTaskWithResult2(int i) { System.out.println('線程' + Thread.currentThread().getName() + ' 開始執行異步任務' + i); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println('線程' + Thread.currentThread().getName() + ' 結束執行異步任務' + i); return new AsyncResult<>('線程' + Thread.currentThread().getName() + ' 執行異步任務:' + i); }
調用返回值:get()是阻塞式,等待當前線程完成才返回值
public void threadTest() { try { List<Future> futures = new ArrayList<>(); for (int i = 0; i < 20; i++) {futures.add(asyncTaskService.executeAsyncTaskWithResult2(i)); } // 獲取值。get是阻塞式,等待當前線程完成才返回值 for (Future<String> future : futures) {System.out.println('返回結果:' + future.get()); } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }補充
實際上,@Async還有一個參數,通過Bean名稱來指定調用的線程池-比如上例中設置的線程池參數不滿足業務需求,可以另外定義合適的線程池,調用時指明使用這個線程池-缺省時springboot會優先使用名稱為’taskExecutor’的線程池,如果沒有找到,才會使用其他類型為TaskExecutor或其子類的線程池。
到此這篇關于SpringBoot中使用多線程的方法示例的文章就介紹到這了,更多相關SpringBoot使用多線程內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!
相關文章:
1. phpstudy apache開啟ssi使用詳解2. CentOS郵件服務器搭建系列—— POP / IMAP 服務器的構建( Dovecot )3. .NET SkiaSharp 生成二維碼驗證碼及指定區域截取方法實現4. IntelliJ IDEA創建web項目的方法5. 存儲于xml中需要的HTML轉義代碼6. docker容器調用yum報錯的解決辦法7. ASP中實現字符部位類似.NET里String對象的PadLeft和PadRight函數8. django創建css文件夾的具體方法9. MyBatis JdbcType 與Oracle、MySql數據類型對應關系說明10. javascript xml xsl取值及數據修改第1/2頁
