java webasynctask_详解Spring/Spring boot异步任务编程WebAsyncTask

今天一起学习下如何在Spring中进行异步编程。我们都知道,web服务器处理请求 request 的线程是从线程池中获取的,这也不难解释,因为当web请求并发数非常大时,如何一个请求进来就创建一条处理线程,由于创建线程和线程上下文切换的开销是比较大的,web服务器最终将面临崩溃。另外,web服务器创建的处理线程从头到尾默认是同步执行的,也就是说,假如处理线程A负责处理请求B,那么当B没有 return 之前,处理线程A是不可以脱身去处理别的请求的,这将极大限制了web服务器的并发处理能力。

因此线程池解决了线程可循环利用的问题,那同步处理请求怎么去解决呢?答案是异步处理。什么是异步处理呢?异步处理主要是让上面的B请求处理完成之前,能够将A线程空闲出来继续去处理别的请求。那么我们可以这样做,在A线程内部重新开启一个线程C去执行任务,让A直接返回给web服务器,继续接受新进来的请求。

在开始下面的讲解之前,我在这里先区别下两个概念:

1、处理线程

处理线程属于web服务器,负责处理用户请求,采用线程池管理

2、异步线程

异步线程属于用户自定义的线程,可采用线程池管理

spring中提供了对异步任务的支持,采用 WebAsyncTask 类即可实现异步任务,同时我们也可以对异步任务设置相应的回调处理,如当任务超时、抛出异常怎么处理等。异步任务通常非常实用,比如我们想让一个可能会处理很长时间的操作交给异步线程去处理,又或者当一笔订单支付完成之后,开启异步任务查询订单的支付结果。

一、正常异步任务

为了演示方便,异步任务的执行采用 Thread.sleep(long) 模拟,现在假设用户请求以下接口 :

http://localhost:7000/demo/getUserWithNoThing.json

异步任务接口定义如下:

/**

* 测试没有发生任何异常的异步任务

*/

@RequestMapping(value = "getUserWithNoThing.json", method = RequestMethod.GET)

public WebAsyncTask getUserWithNoThing() {

// 打印处理线程名

System.err.println("The main Thread name is " + Thread.currentThread().getName());

// 此处模拟开启一个异步任务,超时时间为10s

WebAsyncTask task1 = new WebAsyncTask(10 * 1000L, () -> {

System.err.println("The first Thread name is " + Thread.currentThread().getName());

// 任务处理时间5s,不超时

Thread.sleep(5 * 1000L);

return "任务1顺利执行成功!任何异常都没有抛出!";

});

// 任务执行完成时调用该方法

task1.onCompletion(() -> {

System.err.println("任务1执行完成啦!");

});

System.err.println("task1继续处理其他事情!");

return task1;

}

控制台打印如下:

The main Thread name is http-nio-7000-exec-1

task1继续处理其他事情!

The first Thread name is MvcAsync1

任务1执行完成啦!

浏览器结果如下:

3f4dd3a2f15b94d34aa247c62d6005c4.png

二、抛异常异步任务

接口调用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值