github項目地址:github.com/lgsdaredevi…html
在應用主類中添加@EnableAsync註解 java
@Async
public Future<String> ansync(String name){
try {
Thread.sleep(10000);
logger.info("這裏是異步方法");
logger.info("傳過來的名字是:" + name);
name = "修改的名字";
logger.info("修改後的名字是:" + name);
return new AsyncResult<>("name: " + name);
}catch (Exception e){
return new AsyncResult<>("異常");
}
}
複製代碼
public String requestAnsync(String name){
try {
Long start = System.currentTimeMillis();
Future<String> result = ansync(name);
if (result.isDone()){
name = result.get();
logger.info("異步方法結束,名字改成:" + name);
}
Long end = System.currentTimeMillis();
logger.info("耗時:" + (int)(end-start));
return "hello " + name;
}catch (Exception e){
logger.error("異常");
return "異常";
}
}
複製代碼
若想獲取到返回值,應該輪詢方法獲取,不然若果沒有isDone則不會走下面的方法,或者能夠使用CompletableFuture:git
2018-07-17 11:31:55.390 INFO 5232 --- [nio-8080-exec-6] c.e.async.service.AsyncTestService : 耗時:0
2018-07-17 11:32:05.394 INFO 5232 --- [cTaskExecutor-3] com.example.async.service.AsyncTest : 這裏是異步方法
2018-07-17 11:32:05.394 INFO 5232 --- [cTaskExecutor-3] com.example.async.service.AsyncTest : 傳過來的名字是:ling
2018-07-17 11:32:05.394 INFO 5232 --- [cTaskExecutor-3] com.example.async.service.AsyncTest : 修改後的名字是:修改的名字
複製代碼
若是使用future.get()方法會阻塞線程直到拿到結果。github
@Async
public void noReturnAsync(String name){
try {
Thread.sleep(10000);
logger.info("這裏是異步方法");
logger.info("傳過來的名字是:" + name);
name = "修改的名字";
logger.info("修改後的名字是:" + name);
}catch (Exception e){
}
}
複製代碼
調用異步的方法spring
public String noReturn(String name){
Long start = System.currentTimeMillis();
asyncTest.noReturnAsync(name);
Long end = System.currentTimeMillis();
logger.info("耗時:" + (int)(end-start));
return "hello " + name;
}
複製代碼
若是異步方法變成阻塞的同步方法,可能緣由是異步方法和普通的調用方法在同一個類中,解決方法是將異步方法單獨放到一個類中。 產生緣由:spring對@Transactional註解時也有相似問題,spring掃描時具備@Transactional註解方法的類時,是生成一個代理類,由代理類去開啓關閉事務,而在同一個類中,方法調用是在類體內執行的,spring沒法截獲這個方法調用。 具體參見:Spring Boot使用@Async實現異步調用bash