spring boot異步(Async)任務調(diào)度實現(xiàn)方法
在沒有使用spring boot之前,我們的做法是在配置文件中定義一個任務池,然后將@Async注解的任務丟到任務池中去執(zhí)行,那么在spring boot中,怎么來實現(xiàn)異步任務的調(diào)用了,方法更簡單。
我們還是結(jié)合前面
spring boot整合JMS(ActiveMQ實現(xiàn))
這篇博客里面的代碼來實現(xiàn)。
一、功能說明
消費者在監(jiān)聽到隊列里面的消息時,將接收消息的任務作為異步任務處理。
二、代碼修改
消費者1:
package com.chhliu.springboot.jms; import org.springframework.jms.annotation.JmsListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; @Component public class Consumer { @JmsListener(destination = "mytest.queue") @Async //該方法會異步執(zhí)行,也就是說主線程會直接跳過該方法,而是使用線程池中的線程來執(zhí)行該方法 public void receiveQueue(String text) { System.out.println(Thread.currentThread().getName()+":Consumer收到的報文為:"+text); } }
消費者2:
package com.chhliu.springboot.jms; import org.springframework.jms.annotation.JmsListener; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.stereotype.Component; @Component public class Consumer2 { @JmsListener(destination = "mytest.queue") @SendTo("out.queue") public String receiveQueue(String text) { System.out.println(Thread.currentThread().getName()+":Consumer2收到的報文為:"+text); return "return message"+text; } }
在測試類上添加如下注解:
package com.chhliu.springboot.jms; import javax.jms.Destination; import org.apache.activemq.command.ActiveMQQueue; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest @EnableAsync // 開啟異步任務支持 public class SpringbootJmsApplicationTests { @Autowired private Producer producer; @Test public void contextLoads() throws InterruptedException { Destination destination = new ActiveMQQueue("mytest.queue"); for(int i=0; i<100; i++){ producer.sendMessage(destination, "myname is chhliu!!!"); } } }
三、測試結(jié)果
DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!! 從out.queue隊列收到的回復報文為:return messagemyname is chhliu!!! SimpleAsyncTaskExecutor-45:Consumer收到的報文為:myname is chhliu!!! DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!! 從out.queue隊列收到的回復報文為:return messagemyname is chhliu!!! SimpleAsyncTaskExecutor-46:Consumer收到的報文為:myname is chhliu!!! DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!! 從out.queue隊列收到的回復報文為:return messagemyname is chhliu!!! SimpleAsyncTaskExecutor-47:Consumer收到的報文為:myname is chhliu!!! DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!! 從out.queue隊列收到的回復報文為:return messagemyname is chhliu!!! SimpleAsyncTaskExecutor-48:Consumer收到的報文為:myname is chhliu!!! DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!! 從out.queue隊列收到的回復報文為:return messagemyname is chhliu!!! SimpleAsyncTaskExecutor-49:Consumer收到的報文為:myname is chhliu!!! DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!! 從out.queue隊列收到的回復報文為:return messagemyname is chhliu!!! SimpleAsyncTaskExecutor-50:Consumer收到的報文為:myname is chhliu!!! DefaultMessageListenerContainer-1:Consumer2收到的報文為:myname is chhliu!!!
從上面的測試結(jié)果可以看出,由于消費者2沒有使用異步任務方式,所以消費者2消費消息都是由固定的線程DefaultMessageListenerContainer-1這個線程來處理的,而消費者1由于使用了異步任務的方式,每次處理接收到的消息都是由不同的線程來處理的,當接收到消息時,直接將任務丟到任務池中去處理,而主線程則繼續(xù)跑,從測試結(jié)果中還可以推斷出,spring boot默認使用了newCachedThreadPool線程池來實現(xiàn)。
關(guān)于線程池的具體用法,請參考我的另一篇博文:http://www.dbjr.com.cn/article/134870.htm
四、異步任務有返回
在實際的開發(fā)中,我們會經(jīng)常遇到異步任務有返回的情況,那么在spring boot中,怎么來實現(xiàn)了?
下面以異步發(fā)郵件為例,來進行說明,示例代碼如下:
@Async("taskExecutePool") // 異步任務會提交到taskExecutePool任務池中執(zhí)行 public Future<Response> doSendEmail(MailInfo mailInfo) {// 異步任務返回,使用Future<Response>來異步返回 log.info(Thread.currentThread().getName()+"調(diào)用了doSendEmail異步方法!"); SendMailSession session = null; Response res = new Response(); boolean isOK = sendEmail(mailInfo);// 具體發(fā)郵件的方法 if(isOK){ res.setSuccess(true); }else{ res.setSuccess(false); } return new AsyncResult<Response>(res);
返回之后怎么使用?示例代碼如下:
Future<Response> result = taskJob.doSendEmail(mailInfo); res = result.get(6, TimeUnit.SECONDS);
這樣就可以獲取到異步任務的返回了!
總結(jié)
以上所述是小編給大家介紹的spring boot異步(Async)任務調(diào)度實現(xiàn)方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
java.lang.NullPointerException異常問題解決方案
這篇文章主要介紹了java.lang.NullPointerException異常問題解決方案,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08Netty進階之EventExecutorGroup源碼詳解
這篇文章主要介紹了Netty進階之EventExecutorGroup源碼詳解,EventExecutorGroup繼承了JDK的ScheduledExecutroService,那么它就擁有了執(zhí)行定時任務,執(zhí)行提交的普通任務,需要的朋友可以參考下2023-11-11數(shù)據(jù)庫連接池c3p0配置_動力節(jié)點Java學院整理
這篇文章主要為大家詳細介紹了數(shù)據(jù)庫連接池c3p0配置的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08Component和Configuration注解區(qū)別實例詳解
這篇文章主要為大家介紹了Component和Configuration注解區(qū)別實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11關(guān)于File與MultipartFile的用法概述
這篇文章主要介紹了關(guān)于File與MultipartFile的用法概述,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09一種新的日期處理方式之JavaScript Temporal API
JavaScript Temporal API是一種為Web開發(fā)人員提供了一種新的處理日期和時間數(shù)據(jù)類型的方式。它的目的是使操作日期和時間更加簡單和可靠,而且不用擔心歷史時區(qū)問題或全球化協(xié)調(diào)時間(UTC)之類的問題,感興趣的同學可以參考閱讀2023-05-05