← 返回首页
SpringBoot基础教程(三十五)
发表时间:2023-05-10 15:13:52
Springboot异步任务

在springboot中使用异步,只需要采用注解@EnableAysnc、@Aysnc这两个注解即可。

1.实例

编写异步任务类。

@Component
public class AsyncTask {

    //异步任务没有返回值的。
    @Async
    public void asyncMethodNoReturnValue() throws InterruptedException {
        System.out.println("asyncMethodNoReturnValue thread: "+Thread.currentThread().getName());
        long startTime = System.currentTimeMillis();
        // 异步线程延时 5s 返回结果
        Thread.sleep(5000);
        System.out.println("asyncMethodNoReturnValue thread execute ending....");
        long endTime = System.currentTimeMillis();
        System.out.println("asyncMethodNoReturnValue 总耗时:" + (endTime - startTime)+" ms");
    }

}

编写异步任务接口。

@RestController
public class AsyncController {

    @Resource
    private AsyncTask asyncTask;

    @GetMapping("/async")
    public Map<String, Object> executeAsyncTask() {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            long startTime = System.currentTimeMillis();
            asyncTask.asyncMethodNoReturnValue();
            result.put("code", 200);
            result.put("msg", "success");
            long endTime = System.currentTimeMillis();
            System.out.println("AsyncController=>executeAsyncTask(), 总耗时:" + (endTime - startTime) + " ms");
            return result;
        } catch (Exception ex) {
            ex.printStackTrace();
            result.put("code", 400);
            result.put("msg", "error");
            return result;
        }
    }

}

启动类上添加@EnableAsync注解。

@SpringBootApplication
@EnableAsync
public class AsyncApplication {
    public static void main(String[] args) {
        SpringApplication.run(AsyncApplication.class, args);
    }
}

测试效果:

AsyncController=>executeAsyncTask(), 总耗时:0 ms
asyncMethodNoReturnValue thread: task-2
asyncMethodNoReturnValue thread execute ending....
asyncMethodNoReturnValue 总耗时:5001 ms

异步任务使用注意事项:

启动类开启异步任务开关@EnableAsync,任务类使用@Component @Async作为组件被扫描执行。

2.异步任务使用场景

使用同步任务与异步任务对比:

1)在任务类中添加两个同步任务,模拟两个耗时是计算任务,在Controller中启动两个线程,计算结果。

@Component
public class AsyncTask {

    //同步任1务返回Future
    public Future<Integer> syncMethod1() throws InterruptedException {
        System.out.println("syncMethod1 thread: "+Thread.currentThread().getName());
        // 异步线程延时 5s 返回结果
        Thread.sleep(5000);
        return new AsyncResult<>(100);
    }

    //同步任务2返回Future
    public Future<Integer> syncMethod2() throws InterruptedException {
        System.out.println("syncMethod2 thread: "+Thread.currentThread().getName());
        // 异步线程延时 5s 返回结果
        Thread.sleep(3000);
        return new AsyncResult<>(200);
    }   
}

编写异步任务接口。

@RestController
public class AsyncController {

    @Resource
    private AsyncTask asyncTask;

    @GetMapping("/syncfuture")
    public Map<String, Object> executeSyncFutureTask() {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            long startTime = System.currentTimeMillis();

            Future<Integer> future1 = asyncTask.syncMethod1();
            Future<Integer> future2 = asyncTask.syncMethod2();

            Integer result1 = future1.get();
            Integer result2 = future2.get();

            result.put("code", 200);
            result.put("msg", "success");
            result.put("data", result1+result2);

            long endTime = System.currentTimeMillis();
            System.out.println("AsyncController=>executeSyncFutureTask(), 总耗时:" + (endTime - startTime) + " ms");
            return result;
        } catch (Exception ex) {
            ex.printStackTrace();
            result.put("code", 400);
            result.put("msg", "error");
            return result;
        }
    }   
}

测试效果:

syncMethod1 thread: http-nio-8080-exec-5
syncMethod2 thread: http-nio-8080-exec-5
AsyncController=>executeSyncFutureTask(), 总耗时:8002 ms

2)在任务类中添加两个异步任务,模拟两个耗时是计算任务,在Controller中启动两个线程,计算结果。

@Component
public class AsyncTask {

    //异步任务1返回Future
    @Async
    public Future<Integer> asyncMethod1() throws InterruptedException {
        System.out.println("asyncMethod1 thread: "+Thread.currentThread().getName());
        // 异步线程延时 5s 返回结果
        Thread.sleep(5000);
        return new AsyncResult<>(100);
    }
    //异步任务2返回Future
    @Async
    public Future<Integer> asyncMethod2() throws InterruptedException {
        System.out.println("asyncMethod2 thread: "+Thread.currentThread().getName());
        // 异步线程延时 5s 返回结果
        Thread.sleep(3000);
        return new AsyncResult<>(200);
    }
}

编写异步任务接口。

@RestController
public class AsyncController {

    @Resource
    private AsyncTask asyncTask;

    @GetMapping("/asyncfuture")
    public Map<String, Object> executeAsyncFutureTask() {
        Map<String, Object> result = new HashMap<String, Object>();

        try {
            long startTime = System.currentTimeMillis();
            Future<Integer> future1 = asyncTask.asyncMethod1();
            Future<Integer> future2 = asyncTask.asyncMethod2();

            Integer result1 = future1.get();
            Integer result2 = future2.get();
            result.put("code", 200);
            result.put("msg", "success");
            result.put("data", result1+result2);
            long endTime = System.currentTimeMillis();
            System.out.println("AsyncController=>executeAsyncFutureTask(), 总耗时:" + (endTime - startTime) + " ms");
            return result;
        } catch (Exception ex) {
            ex.printStackTrace();
            result.put("code", 400);
            result.put("msg", "error");
            return result;
        }
    }
}

测试效果:

asyncMethod1 thread: task-3
asyncMethod2 thread: task-4
AsyncController=>executeAsyncFutureTask(), 总耗时:5001 ms