spring boot使用@Async異步任務

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<>("異常");
        }
    }
複製代碼

調用異步方法

  • 一、用Future獲取返回值
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

  • 二、不使用future.get()方法,異步方法不使用Future返回
@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

微信二維碼
相關文章
相關標籤/搜索