springboot异步编程

异步编程

一、异步编程的理解

参考文档:https://blog.51cto.com/stevex/1284437

二、实现步骤

1、开启异步编程支持

在启动类加上下面注解,表示整个项目都可使用,也可以在单独的类上面加,表示只有该类支持

@EnableAsync

2、在service层编写业务时,方法上加 @Async注解

package com.hm.sringboot.service;
import com.hm.sringboot.pojo.User1;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
 * @ClassName
 * @Description TODO
 * @Author ZQS
 * @Date 2020/9/5 0005 16:27
 * @Version 1.0
 **/

@Slf4j
@Component
public class AsyncDemo {
     

    /**
     * 没有返回值的异步任务:例如发送短信邮箱
     */
    @Async
    public void asyncNoResult() throws InterruptedException {
     
        TimeUnit.SECONDS.sleep(2);
        log.info("没有返回值的线程名称为:{}",Thread.currentThread().getName());
        TimeUnit.SECONDS.sleep(2);
    }
    /**
     * 有返回值的 :例如文件上传 需要拿到文件存储的位置/id
     */
    @Async
    public Future<User1> asyncResult ()throws InterruptedException{
     
        TimeUnit.SECONDS.sleep(2);
        log.info("有返回值的线程名称为:{}",Thread.currentThread().getName());
        TimeUnit.SECONDS.sleep(2);
        User1 user1=new User1(1,"小白","rap");
        return new AsyncResult<>(user1);

    }
}

3、编写控制层

package com.hm.sringboot.controller;

import com.hm.sringboot.pojo.User1;
import com.hm.sringboot.service.AsyncDemo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * @ClassName
 * @Description TODO
 * @Author ZQS
 * @Date 2020/9/5 0005 16:44
 * @Version 1.0
 **/
@RestController
@RequestMapping("/")
@Slf4j
public class AsyncController {
     

    @Autowired
    AsyncDemo asyncDemo;

    @GetMapping("async1")
    public String async1() throws ExecutionException, InterruptedException {
     
        asyncDemo.asyncNoResult();
        return "方法调用成功";
    }

    @GetMapping("async2")
    public String async2() throws InterruptedException, ExecutionException {
     
        Future<User1> stringFuture = asyncDemo.asyncResult();
        User1 user1 = stringFuture.get();
        log.info("调用有返回值的异步方法" + "成功");
        return "成功";
    }
}

4、注意点(有返回值和无返回值)

A:当调用无返回值时候,访问页面直接返回
B:当调用有返回值时候,访问页面会等待2秒执行(TimeUnit.SECONDS.sleep(2))

原因:

1、因为控制层要拿到service层的的结果(主线程要拿到service线程的结果),才能返回给前台数据,而service层又执行睡眠方法

2、当控制层不需要拿到service的结果时,并不需要等待

所以等待原因是控制层需要拿到service层的数据

你可能感兴趣的:(SpringBoot框架,spring,boot,多线程)