1. 程式人生 > >springboot的非同步任務(帶返回值和不帶返回值的處理)

springboot的非同步任務(帶返回值和不帶返回值的處理)

package com.example.demo.async;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.util.concurrent.Future;

//注意:1、要把非同步任務寫進一個類裡面而不能直接寫在controller中
//      2、如果需要拿到結果,則需要在呼叫處判斷全部的task.isDone()來確定非同步任務的完成
@Component

//非同步類註解,表明整個類的方法都是非同步方法,如果把這個註解加在某一個方法上而不是某一個類則表明僅僅是這個方法才是非同步方法
@Async
public class As {
    //下面是3個非同步任務(不帶返回值的)
    public void task1() throws InterruptedException {
        long begin=System.currentTimeMillis();
        Thread.sleep(3000l);
        long end=System.currentTimeMillis();
        System.out.println("任務1耗時"+(end-begin));
    }

    public void task2() throws InterruptedException {
        long begin=System.currentTimeMillis();
        Thread.sleep(2000l);
        long end=System.currentTimeMillis();
        System.out.println("任務2耗時"+(end-begin));
    }

    public void task3() throws InterruptedException {
        long begin=System.currentTimeMillis();
        Thread.sleep(1000l);
        long end=System.currentTimeMillis();
        System.out.println("任務3耗時"+(end-begin));
    }

    //下面是3個非同步任務(帶返回值的,可以在調用出取地返回值)
    public Future<String> task4() throws InterruptedException {
        long begin=System.currentTimeMillis();
        Thread.sleep(3000l);
        long end=System.currentTimeMillis();
        return new AsyncResult<String>("任務4耗時"+(end-begin));
    }

    public Future<String> task5() throws InterruptedException {
        long begin=System.currentTimeMillis();
        Thread.sleep(2000l);
        long end=System.currentTimeMillis();
        return new AsyncResult<String>("任務5耗時"+(end-begin));
    }

    public Future<String> task6() throws InterruptedException {
        long begin=System.currentTimeMillis();
        Thread.sleep(1000l);
        long end=System.currentTimeMillis();
        return new AsyncResult<String>("任務6耗時"+(end-begin));
    }
}

controller測試控制器

package com.example.demo.controller;

import com.example.demo.async.As;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@RestController
public class He {
	//注入非同步類
    @Autowired
    private As as;

    //測試非同步任務沒帶返回值的,直接主執行緒瞬間就通過了
    @RequestMapping("/as")
    public Object as() throws InterruptedException {
        long begin=System.currentTimeMillis();
        as.task1();
        as.task2();
        as.task3();
        long end=System.currentTimeMillis();
        return "總耗時+"+(end-begin);
    }

    //測試非同步任務帶返回值的,總耗時是最慢的那個任務的耗時
    @RequestMapping("/asHava")
    public Object ash() throws InterruptedException, ExecutionException {
        long begin=System.currentTimeMillis();
        Future<String> task4=as.task4();
        Future<String> task5=as.task5();
        Future<String> task6=as.task6();
        //先小堵塞主執行緒一會,用以拿到非同步任務返回值
        while (!(task4.isDone()&&task5.isDone()&&task6.isDone())){

        }
        long end=System.currentTimeMillis();
        //取得非同步任務的返回值並檢視總耗時
        return "總耗時+"+(end-begin)+"   task4結果:"+task4.get()+"  task5結果:"+task5.get()+"  task6結果:"+task6.get();
        //結果是3s左右,因為進入介面,三個非同步任務瞬間開啟,再瞬間到while這兒堵起
        //由於三個非同步任務幾乎是同時開啟的,所以等最慢的那個非同步任務完成以後,肯定所有的非同步任務都完成了
        //所以while這時才都為true,那麼放開while,所以結果就是最慢的那個非同步任務的時間
        //如果說不用這種非同步取值而用同步的話,那麼時間就是1+2+3就是6s左右,而不是最慢的那個任務的時間
    }
}