spring@Async註解實現異步方法調用

 

概述

如何實現異步方法調用,不少人首先會想到使用線程或者線程池技術,springboot中有一個很簡單的方法能夠實現異步方法調用,那就是在方法上使用@Async註解java

例子

首先在Springboot啓動類上添加@EnableAsync註解,代表使用@Async註解spring

@SpringBootApplication
@EnableAsync
public class Application{

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

異步調用測試類api

package com.example.mongo_demo.test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
* created by qinming on 2018/5/17
**/
@Component
public class AsyncTest {
public static final Logger LOGGER = LoggerFactory.getLogger(AsyncTest.class);

@Async
public void asyn1() throws InterruptedException {
Long timeMilles = System.currentTimeMillis();
Thread.sleep(7000);
LOGGER.error("》》》》》》》》》》》》asyn1耗時:{}《《《《《《《《《",System.currentTimeMillis()-timeMilles);
}
@Async
public void asyn2() throws InterruptedException {
Long timeMilles = System.currentTimeMillis();
Thread.sleep(7000);
LOGGER.error("》》》》》》》》》》》》asyn2耗時:{}《《《《《《《《《",System.currentTimeMillis()-timeMilles);
}
@Async
public void asyn3() throws InterruptedException {
Long timeMilles = System.currentTimeMillis();
Thread.sleep(10000);
LOGGER.error("》》》》》》》》》》》》asyn3耗時:{}《《《《《《《《《",System.currentTimeMillis()-timeMilles);
}
}

經過一個簡單的接口測試便可springboot

/**
* created by qinming on 2018/5/17
**/
@RestController
@RequestMapping("/api")
public class DemostrationController {
@Autowired
private AsyncTest asyncTest;
public static final Logger LOGGER = LoggerFactory.getLogger(DemostrationController.class);
@RequestMapping("/async/test")
public String get() throws InterruptedException {
long timeMillis = System.currentTimeMillis();
asyncTest.asyn1();
asyncTest.asyn2();
asyncTest.asyn3();
Thread.sleep(1000);
LOGGER.error("//////耗時:{}",System.currentTimeMillis()-timeMillis);
return "";
}
}

結果以下:app

2018-05-17 14:27:40.252 ERROR 7843 --- [nio-8080-exec-1] c.e.m.ctrl.DemostrationController : //////耗時:1019
2018-05-17 14:27:46.253 ERROR 7843 --- [cTaskExecutor-1] com.example.mongo_demo.test.AsyncTest : 》》》》》》》》》》》》asyn1耗時:7003《《《《《《《《《
2018-05-17 14:27:46.255 ERROR 7843 --- [cTaskExecutor-2] com.example.mongo_demo.test.AsyncTest : 》》》》》》》》》》》》asyn2耗時:7005《《《《《《《《《
2018-05-17 14:27:49.254 ERROR 7843 --- [cTaskExecutor-3] com.example.mongo_demo.test.AsyncTest : 》》》》》》》》》》》》asyn3耗時:10004《《《《《《《《《

這樣就實現了異步方法的簡單調用異步

帶有返回值的方法如何使用@Async註解

使用@Async註解的方法返回值爲java.util.concurrent.Future 的實現類 org.springframework.scheduling.annotation.AsyncResult 類型,代碼以下:async

/**
* created by qinming on 2018/5/17
**/
@Component
public class AsyncWIthReturnValueTest {
public static final Logger LOGGER = LoggerFactory.getLogger(AsyncWIthReturnValueTest.class);

@Async
public Future<String> aysnc1() throws InterruptedException {
Long st = System.currentTimeMillis();
LOGGER.error(">>>>>>>aysnc1 start at {}>>>>>",st);
Thread.sleep(7000);
long end =System.currentTimeMillis();
LOGGER.error(">>>>>>>aysnc1 cost :{}>>>>>",end - st);
return new AsyncResult<String>("aysnc1 is done");
}
@Async
public Future<String> aysnc2() throws InterruptedException {
Long st = System.currentTimeMillis();
LOGGER.error(">>>>>>>aysnc2 start at {}>>>>>",st);
Thread.sleep(7000);
long end =System.currentTimeMillis();
LOGGER.error(">>>>>>>aysnc2 cost :{}>>>>>",end - st);
return new AsyncResult<String>("aysnc2 is done");
}
@Async
public Future<String> aysnc3() throws InterruptedException {
Long st = System.currentTimeMillis();
LOGGER.error(">>>>>>>aysnc3 start at {}>>>>>",st);
Thread.sleep(7000);
long end =System.currentTimeMillis();
LOGGER.error(">>>>>>>aysnc3 cost :{}>>>>>",end - st);
return new AsyncResult<String>("aysnc3 is done");
}
}

調用方法例子以下:測試

@RequestMapping("/async/test")
public String get() throws InterruptedException, ExecutionException {
long timeMillis = System.currentTimeMillis();
Future<String> async1 = asyncWIthReturnValueTest.aysnc1();
Future<String> async2 = asyncWIthReturnValueTest.aysnc2();
Future<String> async3 = asyncWIthReturnValueTest.aysnc3();
while (true) {
if (async1.isDone()){
LOGGER.error("----{}1-------",async1.get());
}
if (async2.isDone()){
LOGGER.error("----{}2-------",async2.get());
}
if (async3.isDone()){
LOGGER.error("----{}3-------",async3.get());
}
if (async1.isDone() && async2.isDone() && async3.isDone()) {
break;
}
Thread.sleep(1000);
}
LOGGER.error("//////耗時:{}",System.currentTimeMillis()-timeMillis);
return "SUCCESS";
}
相關文章
相關標籤/搜索