springboot的异步任务(带返回值和不带返回值的处理)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_36984017/article/details/82952354

注意:在用异步任务之前先给启动类加@EnableAsync这个注解

新建异步任务包和在包里面建异步任务类

As.java异步类

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左右,而不是最慢的那个任务的时间
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36984017/article/details/82952354