十年網站開發(fā)經驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網站問題一站解決
本文主要給大家介紹了關于spring boot異步調用方式@Async的相關內容,分享出來供大家參考學習,下面來一起看看詳細的介紹:
太和網站制作公司哪家好,找創(chuàng)新互聯(lián)建站!從網頁設計、網站建設、微信開發(fā)、APP開發(fā)、響應式網站設計等網站項目制作,到程序開發(fā),運營維護。創(chuàng)新互聯(lián)建站成立于2013年到現(xiàn)在10年的時間,我們擁有了豐富的建站經驗和運維經驗,來保證我們的工作的順利進行。專注于網站建設就選創(chuàng)新互聯(lián)建站。
1.使用背景
在日常開發(fā)的項目中,當訪問其他人的接口較慢或者做耗時任務時,不想程序一直卡在耗時任務上,想程序能夠并行執(zhí)行,我們可以使用多線程來并行的處理任務,也可以使用spring提供的異步處理方式@Async。
2.異步處理方式
3.@Async不返回數(shù)據(jù)
使用@EnableAsync啟用異步注解
@Configuration @EnableAsync @Slf4j public class AsyncConfig{ }
在異步處理的方法dealNoReturnTask上添加注解@Async
@Component @Slf4j public class AsyncTask { @Async public void dealNoReturnTask(){ log.info("Thread {} deal No Return Task start", Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } log.info("Thread {} deal No Return Task end at {}", Thread.currentThread().getName(), System.currentTimeMillis()); } }
Test測試類:
@SpringBootTest(classes = SpringbootApplication.class) @RunWith(SpringJUnit4ClassRunner.class) @Slf4j public class AsyncTest { @Autowired private AsyncTask asyncTask; @Test public void testDealNoReturnTask(){ asyncTask.dealNoReturnTask(); try { log.info("begin to deal other Task!"); Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } }
日志打印結果為:
begin to deal other Task! AsyncExecutorThread-1 deal No Return Task start AsyncExecutorThread-1 deal No Return Task end at 1499751227034
從日志中我們可以看出,方法dealNoReturnTask()
是異步執(zhí)行完成的。
dealNoReturnTask()
設置sleep 3s是為了模擬耗時任務
testDealNoReturnTask()
設置sleep 10s是為了確認異步是否執(zhí)行完成
4.@Async返回數(shù)據(jù)
異步調用返回數(shù)據(jù),F(xiàn)uture表示在未來某個點獲取執(zhí)行結果,返回數(shù)據(jù)類型可以自定義
@Async public FuturedealHaveReturnTask() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } JSONObject jsonObject = new JSONObject(); jsonObject.put("thread", Thread.currentThread().getName()); jsonObject.put("time", System.currentTimeMillis()); return new AsyncResult (jsonObject.toJSONString()); }
測試類用isCancelled判斷異步任務是否取消,isDone判斷任務是否執(zhí)行結束
@Test public void testDealHaveReturnTask() throws Exception { Futurefuture = asyncTask.dealHaveReturnTask(); log.info("begin to deal other Task!"); while (true) { if(future.isCancelled()){ log.info("deal async task is Cancelled"); break; } if (future.isDone() ) { log.info("deal async task is Done"); log.info("return result is " + future.get()); break; } log.info("wait async task to end ..."); Thread.sleep(1000); } }
日志打印如下,我們可以看出任務一直在等待異步任務執(zhí)行完畢,用future.get()
來獲取異步任務的返回結果
begin to deal other Task! wait async task to end ... wait async task to end ... wait async task to end ... wait async task to end ... deal async task is Done return result is {"thread":"AsyncExecutorThread-1","time":1499752617330}
4.異常處理
我們可以實現(xiàn)AsyncConfigurer接口,也可以繼承AsyncConfigurerSupport類來實現(xiàn)
在方法getAsyncExecutor()
中創(chuàng)建線程池的時候,必須使用 executor.initialize()
,不然在調用時會報線程池未初始化的異常。
如果使用threadPoolTaskExecutor()
來定義bean,則不需要初始化
@Configuration @EnableAsync @Slf4j public class AsyncConfig implements AsyncConfigurer { // @Bean // public ThreadPoolTaskExecutor threadPoolTaskExecutor(){ // ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // executor.setCorePoolSize(10); // executor.setMaxPoolSize(100); // executor.setQueueCapacity(100); // return executor; // } @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(100); executor.setQueueCapacity(100); executor.setThreadNamePrefix("AsyncExecutorThread-"); executor.initialize(); //如果不初始化,導致找到不到執(zhí)行器 return executor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new AsyncExceptionHandler(); } }
異步異常處理類:
@Slf4j public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler { @Override public void handleUncaughtException(Throwable ex, Method method, Object... params) { log.info("Async method: {} has uncaught exception,params:{}", method.getName(), JSON.toJSONString(params)); if (ex instanceof AsyncException) { AsyncException asyncException = (AsyncException) ex; log.info("asyncException:{}",asyncException.getErrorMessage()); } log.info("Exception :"); ex.printStackTrace(); } }
異步處理異常類:
@Data @AllArgsConstructor public class AsyncException extends Exception { private int code; private String errorMessage; }
handleUncaughtException()
會捕獲指定異常,原有任務還會繼續(xù)運行,直到結束。總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對創(chuàng)新互聯(lián)的支持。