使用@Async注解执行异步任务

      遇到的问题,项目中在自己的一个方法里面需要同时调用同时的多个接口,但是同时的接口响应速度有很慢,导致自己的方法返回很慢,然后前端请求的时候,就超时了。后来了解到自己调同时的接口是串行的,只有等待第一个请求的接口返回数据后,才能继续请求第二个接口...

后来上网找到原来可以并行请求多个接口,这样就不用等请求第一个接口响应就能调第二个接口,响应会比串行请求快很多。

1、串行和并行调用的理解

串行执行:有多个任务串行执行的话,第二个任务需要等第一个任务执行完成后才能执行。

并行执行:有多个任务并行执行的话,第二个任务不需要等第一个任务执行完就可以执行。

 

2、实现步骤

2.1开启异步@Async注解支持

在springboot项目中的启动类添加@EnableAsync注解

@SpringBootApplication
@EnableAsync
public class AsyncApplication {

    public static void main(String[] args) {

        SpringApplication.run(AsyncApplication.class, args);
    }

}

 2.2 写需要异步执行的任务

在需要异步执行的方法上面加@Async注解

public class ProductListTask {

    private static Random random = new Random();

    @Async
    public Future<List<Product>> getProductOne() throws Exception {

        List<Product> products = new ArrayList<>();
        products.add(new Product("小米8", 200));
        products.add(new Product("小米9", 300));

        System.out.println("开始做任务一");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        System.out.println("完成任务一,耗时:" + (end - start) + "毫秒");
        return new AsyncResult<>(products);
    }

    @Async
    public Future<Product> getProductTwo() throws Exception {
        System.out.println("开始做任务二");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        System.out.println("完成任务二,耗时:" + (end - start) + "毫秒");
        return new AsyncResult<>(new Product("苹果手机", 4000));
    }

    @Async
    public Future<Product> getProductThree() throws Exception {
        System.out.println("开始做任务三");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        System.out.println("完成任务三,耗时:" + (end - start) + "毫秒");
        return new AsyncResult<>(new Product("华为手机", 3000));
    }

}

2.3 调用异步任务

@RunWith(SpringRunner.class)
@SpringBootTest
public class AsyncTaskTest {
    
    @Autowired
    private ProductTask productTask;

    /**
     * 测试有返回值的方法,并获取返回值
     */
    @Test
    public void testGetProduct() throws Exception {

        //执行任务一
        Future<Product> productFutureOne = productTask.getProductOne();

        //执行任务二
        Future<Product> productFutureTwo = productTask.getProductTwo();

        //执行任务二
        Future<Product> productFutureThree = productTask.getProductThree();

        //获取返回值
        Product productOne = productFutureOne.get();
        System.out.println("productOne = " + productOne.getPName());

        Product productTwo = productFutureTwo.get();
        System.out.println("productTwo = " + productTwo.getPName());

        Product productThree = productFutureThree.get();
        System.out.println("productThree = " + productThree.getPName());
    }

}

执行结果如下

3、总结:

3.1、异步任务和调用异步任务的方法要在不同的类中

3.2、如果需要获取异步任务执行返回的值的话,应该推迟获取

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值