使用spring的异步模式@EnableAsync与@Async配合Future与AsyncResult实现异步调用服务并行,也可以并行sql查询加速系统

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/c5113620/article/details/90035551

spring boot项目
服务类上注解@EnableAsync开启扫描方法上的@Async注解,当其他bean调用这个被@Async注解的方法时,spring会通过代理,在子线程里执行,达到异步调用与并行执行的目的

注意

  1. 不能在类内部 (bean内部,spring无法感知) 调用@Async (就是要),spring无法感知到,所以不会再子线程执行
    @Async生效需要一个bean(controller)调用另一个bean(service)的方法
  2. 如果有返回值,返回值是Future类型的包装
//controller.java

    @Autowired
    private FakeService fakeService;

    @GetMapping("/slow")
    public String slow() {

        StopWatch watch = new StopWatch("my watch");

        //通常模式service调用
        watch.start("slowServiceNormal");
        fakeService.slowService();
        fakeService.slowService();
        watch.stop();

        //异步模式,在子线程各自独立调用service,有返回值
        watch.start("slowService async with return");
        Future<Long> res1 = fakeService.slowServiceAsync();
        Future<Long> res2 = fakeService.slowServiceAsync();

        try {
            res1.get();
            res2.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        watch.stop();

        //无返回值调用,直接返回,子线程继续工作
        watch.start("slowServiceNoReturn");
        fakeService.slowServiceNoReturn();
        fakeService.slowServiceNoReturn();
        watch.stop();

        System.out.println(watch.prettyPrint());

        return "done";
    }
package boottest;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * @author zhanghui
 * @date 2019/5/9
 */
@Service
@EnableAsync
public class FakeService {

    public long slowService(){
        System.out.println("slowServiceNormal");
        LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(5));
        System.out.println("slowServiceNormal done");
        return 5;
    }

    //异步调用,有返回值,必须是Future类型,不然报错
    @Async
    public Future<Long> slowServiceAsync(){
        System.out.println("slowServiceAsync");
        return new AsyncResult(slowService());
    }

    @Async
    public void slowServiceNoReturn(){
        System.out.println("slowServiceNoReturn");
        slowService();
    }
}

猜你喜欢

转载自blog.csdn.net/c5113620/article/details/90035551