Spring中@Async异步回调

有一篇我们讲了用java的线程池跑批量任务,虽然也很方便,但是实际开发中,我们大部分都是使用Spring的框架,一个@Async注解就可以实现异步调用,让并发编程变的更简单了,与此同时我们也没办法通过方法的返回值能直接拿到结果了,所以需要用到异步回调,子线程做完之后回调给主线程

项目背景不用多说了,一般都是spring-boot

准备

@EnableAsync添加在启动类或者带@Configuration的都行

创建job

主要是利用Future这个函数处理回调,方法异步执行直接返回该类,任务是否执行完会提供isDone方法判断,最后可通过get方法获取返回值

@Async需要在不同的类使用,这个不再赘述了,用过的应该都知道原因了,我们创建一个Service

import java.util.concurrent.Future;

public interface AsyncService {

    /**
     * 多线程下载
     * 这是一个带有回调的多线程函数
     *
     * @param url 下载url
     * @param savePath 下载路径
     * @return
     */
    Future<String> downloadFileJob(String url, String savePath);

}

对应的Impl实现类

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

import java.util.concurrent.Future;

@Service
public class AsyncServiceImpl implements AsyncService{

    @Async
    @Override
    public Future<String> downloadFileJob(String url, String savePath) {
        // 模拟下载耗时任务
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 模拟完成任务后返回参数
        String result = "任务完成";
        return new AsyncResult<>(result);
    }

}

测试

创建一个单元测试类

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.scheduling.annotation.EnableAsync;

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

@EnableAsync
@SpringBootTest
public class ApplicationTests {

    @Autowired
    private AsyncService asyncService;

    @Test
    public void test() throws InterruptedException, ExecutionException {
        // 异步任务列表
        List<Future<String>> jobList = new ArrayList<>();

        // 多线程跑任务
        long start = System.currentTimeMillis();
        // 执行批量任务
        for (int i = 1; i <= 200; i++) {
            jobList.add(asyncService.downloadFileJob("https://xxx.com", "/temp/file/"));
        }
        // 查看整批任务是否执行完毕
        for (Future<String> job : jobList) {
            // 使用Future的isDone()方法返回该方法是否执行完成,如果异步方法全部执行完,跳出循环
            while (!job.isDone()) {
                Thread.sleep(100);// 每隔100毫秒看一下是否执行完毕了
            }
            // get()方法获取异步任务返回值
            String result = job.get();
            System.out.println("多线程执行job返回内容:" + result);
        }
        long end = System.currentTimeMillis();
        System.out.println("多线程执行总耗时:" + (end - start) / 1000 + "s");

        // 单线程跑任务
        start = System.currentTimeMillis();
        for (int i = 1; i <= 200; i++) {
            new AsyncServiceImpl().downloadFileJob("https://xxx.com", "/temp/file/");
        }
        end = System.currentTimeMillis();
        System.out.println("单线程执行总耗时:" + (end - start) / 1000 + "s");
    }

}

结果

如图所示,效果很明显了
在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值