SpringBoot异步处理

发布时间:2024年01月16日

Spring boot异步处理

业务场景:

如执行数据库备份任务,前端发起请求到后端,后端备份数据库的处理逻辑需要很长一段时间,此时前端会一直等待后端返回结果,给用户给等待时间过长,这是就要考虑异步处理了,如客户点击数据库备份操作后之间返回响应结果,至于备份多久后台异步在处理,处理完成后看日志就行了

1. 异步任务方式1

使用线程池,创建新的线程去处理,如下:

/**
     * 异步处理1:线程池,创建新线程处理
     * @return
     */
    @RequestMapping(value = "test3",method = RequestMethod.GET)
    public String test3(){
        ExecutorService service = Executors.newFixedThreadPool(5);
        RunnableTask1 task1 = new RunnableTask1();
        service.execute(task1);
        logger.info("=========》当前线程名:"+Thread.currentThread().getName());
        return "异步,正在解析......";
    }

线程任务

public class RunnableTask1 implements Runnable{
    private final Logger logger = LoggerFactory.getLogger(getClass());
    @Override
    public void run(){
        Building building = new Building();
        synchronized (building){
            try {
                for (int i = 1;i <= 100;i++){
                    System.out.println(Thread.currentThread().getName()+"----------异步:>"+i);
                    building.wait(200);
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
    }
}

我们看控制台,会发现,主线程,和处理任务的线程,不是一个线程,也就是,当页面请求后,主线程会返回我们想要返回的标识,这里返回的是一个字符串:异步,正在解析…,而线程池新开了一个线程,在后台处理业务逻辑。所以,此时访问接口后,会立马返回,页面不用等待,处理逻辑在后台默默进行。

2. 异步任务方式2

这种方式,是springBoot自身的一种异步方式,使用注解实现,非常方便,我们在想要异步执行的方法上加上@Async注解,在controller上加上@EnableAsync,即可。注意,这里的异步方法,只能在自身之外调用,在本类调用是无效的。

controller如下

@RestController
@RequestMapping("test")
@EnableAsync
public class LoginController {
    private final org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private LoginService loginService;
    /**
     * 异步处理2:使用springBoot自带async注解
     */
    @RequestMapping(value = "test1",method = RequestMethod.GET)
    public String test1(){
        loginService.getTest1();
        logger.info("============>"+Thread.currentThread().getName());
        return "异步,正在解析......";
    }

serviceImpl 如下

/**异步方法
 * 有@Async注解的方法,默认就是异步执行的,会在默认的线程池中执行,但是此方法不能在本类调用;启动类需添加直接开启异步执行@EnableAsync。
 * */
@Async
@Override
public String getTest1(){
    Building building = new Building();
    synchronized (building){
        try {
            for (int i = 1;i <= 100;i++){
                logger.info(Thread.currentThread().getName()+"----------异步:>"+i);
                building.wait(200);
            }
            return "执行异步任务完毕";
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
    return Thread.currentThread().getName()+"执行完毕";
}

看控制台,会发现,页面发出请求后,主线程会返回,而内置的线程池会新开线程,在后台执行任务。此时页面不用等待,可以继续其他操作。

文章来源:https://blog.csdn.net/yuanjinshenglife/article/details/135632436
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。