1、任務(wù)執(zhí)行和調(diào)度
創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比晉城網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式晉城網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋晉城地區(qū)。費(fèi)用合理售后完善,十年實(shí)體公司更值得信賴。
Spring用TaskExecutor和TaskScheduler接口提供了異步執(zhí)行和調(diào)度任務(wù)的抽象。
Spring的TaskExecutor和java.util.concurrent.Executor接口時(shí)一樣的,這個(gè)接口只有一個(gè)方法execute(Runnable task)。
1.1、TaskExecutor類型
Spring已經(jīng)內(nèi)置了許多TaskExecutor的實(shí)現(xiàn),你沒有必要自己去實(shí)現(xiàn):
1.2、注解支持調(diào)度和異步執(zhí)行
To enable support for @Scheduled and @Async annotations add @EnableScheduling and @EnableAsync to one of your
@Configuration classes: @Configuration @EnableAsync @EnableScheduling public class AppConfig { }
特別注意
The default advice mode for processing @Async annotations is "proxy" which allows for interception of calls through the proxy only; local calls within the same class cannot get intercepted that way. For a more advanced mode of interception, consider switching to "aspectj" mode in combination with compile-time or load-time weaving.
默認(rèn)是用代理去處理@Async的,因此,相同類中的方法調(diào)用帶@Async的方法是無法異步的,這種情況仍然是同步。
舉個(gè)例子:下面這種,在外部直接調(diào)用sayHi()是可以異步執(zhí)行的,而調(diào)用sayHello()時(shí)sayHi()仍然是同步執(zhí)行
public class A { public void sayHello() { sayHi(); } @Async public void sayHi() { } }
1.3、@Async注解
在方法上加@Async注解表示這是一個(gè)異步調(diào)用。換句話說,方法的調(diào)用者會(huì)立即得到返回,并且實(shí)際的方法執(zhí)行是想Spring的TaskExecutor提交了一個(gè)任務(wù)。
In other words, the caller will return immediately upon invocation and the actual execution of the method will occur in a task that has been submitted to a Spring TaskExecutor.
@Async void doSomething() { // this will be executed asynchronously }
@Async void doSomething(String s) { // this will be executed asynchronously }
@Async Future<String> returnSomething(int i) { // this will be executed asynchronously }
注意:
@Async methods may not only declare a regular java.util.concurrent.Future return type but also Spring's org.springframework.util.concurrent.ListenableFuture or, as of Spring 4.2, JDK 8's java.util.concurrent.CompletableFuture: for richer interaction with the asynchronous task and for immediate composition with further processing steps.
1.4、@Async限定Executor
默認(rèn)情況下,當(dāng)在方法上加@Async注解時(shí),將會(huì)使用一個(gè)支持注解驅(qū)動(dòng)的Executor。然而,@Async注解的value值可以指定一個(gè)別的Executor
@Async("otherExecutor") void doSomething(String s) { // this will be executed asynchronously by "otherExecutor" }
這里,otherExecutor是Spring容器中任意Executor bean的名字。
1.5、@Async異常管理
當(dāng)一個(gè)@Async方法有一個(gè)Future類型的返回值時(shí),就很容易管理在調(diào)Future的get()方法獲取任務(wù)的執(zhí)行結(jié)果時(shí)拋出的異常。如果返回類型是void,那么異常是不會(huì)被捕獲到的。
public class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler { @Override public void handleUncaughtException(Throwable ex, Method method, Object... params) { // handle exception } }
2、線程池配置
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @Configuration @EnableAsync public class TaskExecutorConfig { private Integer corePoolSize = 30; private Integer maxPoolSize = 50; private Integer keepAliveSeconds = 300; // private Integer queueCapacity = 2000; @Bean("myThreadPoolTaskExecutor") public ThreadPoolTaskExecutor myThreadPoolTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setKeepAliveSeconds(keepAliveSeconds); // executor.setQueueCapacity(queueCapacity); executor.setWaitForTasksToCompleteOnShutdown(true); executor.initialize(); return executor; } }
調(diào)用
@Async("myThreadPoolTaskExecutor") @Override public void present(CouponPresentLogEntity entity) { try { CouponBaseResponse rst = couponSendRpcService.send(entity.getUserId(), entity.getCouponBatchKey(), "1", entity.getVendorId()); if (null != rst && rst.isSuccess()) { entity.setStatus(PresentStatusEnum.SUCCESS.getType()); }else { String reason = (null == rst) ? "響應(yīng)異常" : rst.getMsg(); entity.setFailureReason(reason); entity.setStatus(PresentStatusEnum.FAILURE.getType()); } }catch (Exception ex) { log.error(ex.getMessage(), ex); entity.setFailureReason(ex.getMessage()); entity.setStatus(PresentStatusEnum.FAILURE.getType()); } couponPresentLogDao.update(entity); }
結(jié)果
[INFO ] 2018-05-09 16:27:39.887 [myThreadPoolTaskExecutor-1] [com.ourhours.coupon.rpc.dubbo.ReceiveLogFilter] - receive method-name:send; arguments:[10046031,"4d7cc32f8f7e4b00bca56f6bf4b3b658","1",10001]
[INFO ] 2018-05-09 16:27:39.889 [myThreadPoolTaskExecutor-2] [com.ourhours.coupon.rpc.dubbo.ReceiveLogFilter] - receive method-name:send; arguments:[10046031,"4d7cc32f8f7e4b00bca56f6bf4b3b658","1",10001]
參考:
Spring Framework Reference Documentation 4.3.17.RELEASE
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
新聞標(biāo)題:SpringBoot@Async異步任務(wù)執(zhí)行方法
網(wǎng)頁網(wǎng)址:http://sd-ha.com/article40/iecdeo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、企業(yè)建站、外貿(mào)網(wǎng)站建設(shè)、電子商務(wù)、網(wǎng)站營銷、面包屑導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)