java异步处理rest服务_010 异步处理Rest服务

本文详细介绍了如何在Java中使用Callable和DeferredResult进行异步处理REST服务。首先展示了如何通过Callable创建异步任务,然后讨论了使用DeferredResult解决线程间通信的问题,并给出了具体代码实现。最后,提到了异步线程配置的相关注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:任务

1.任务

使用Runnable异步处理Rest服务

使用DefaultResult异步处理Rest服务

异步处理的配置

2.原理图说明

3e67072a0de7ef8551938c7dcac76893.png

二:Callable进行异步处理

1.程序

新建一个anysc的包

1 packagecom.cao.web.async;2

3 importjava.util.concurrent.Callable;4

5 importorg.slf4j.Logger;6 importorg.slf4j.LoggerFactory;7 importorg.springframework.web.bind.annotation.RequestMapping;8 importorg.springframework.web.bind.annotation.RestController;9

10 @RestController11 public classAsyncController {12 private Logger logger=LoggerFactory.getLogger(getClass());13

14 @RequestMapping("/order")15 public Callable order() throwsException {16 logger.info("主线程开始");17 //业务逻辑放在副线程中

18 Callable result=new Callable() {19

20 @Override21 public String call() throwsException {22 logger.info("副线程开始");23 Thread.sleep(5000);24 logger.info("副线程返回");25 return "success";26 }27

28 };29

30 logger.info("主线程返回");31

32 returnresult;33 }34

35 }

2.效果

重点关注时间

f1040f4ed4390fee4dea9f5caec42c9e.png

三:使用DeferredResult

1.问题

方式一是有问题的,因为副线程是需要主线程调用起来的。

是写在主线程中的。

有些场景是不合适的。

线程间使用DeferredResult沟通起来。

2.场景如下:

ae0822213d4ab8e0b29aad43b19f2648.png

3.程序

程序太多,有点复杂

控制器

1 packagecom.cao.web.async;2

3 importjava.util.concurrent.Callable;4

5 importorg.apache.commons.lang.RandomStringUtils;6 importorg.slf4j.Logger;7 importorg.slf4j.LoggerFactory;8 importorg.springframework.beans.factory.annotation.Autowired;9 importorg.springframework.web.bind.annotation.RequestMapping;10 importorg.springframework.web.bind.annotation.RestController;11 importorg.springframework.web.context.request.async.DeferredResult;12

13 @RestController14 public classAsyncController {15 private Logger logger=LoggerFactory.getLogger(getClass());16 @Autowired17 privateQueue queue;18

19 @Autowired20 privateDeferredResultHolder deferredResultHolder;21

22 /**

23 * 主要是验证Callable24 *@return

25 *@throwsException26 */

27 @RequestMapping("/order")28 public Callable order() throwsException {29 logger.info("主线程开始");30 //业务逻辑放在副线程中

31 Callable result=new Callable() {32

33 @Override34 public String call() throwsException {35 logger.info("副线程开始");36 Thread.sleep(5000);37 logger.info("副线程返回");38 return "success";39 }40

41 };42

43 logger.info("主线程返回");44

45 returnresult;46 }47 /**

48 * 主要是验证49 *@return

50 *@throwsException51 */

52 @RequestMapping("/newOrder")53 public DeferredResult newOrder() throwsException {54 logger.info("主线程开始");55 //56 String oderNumber=RandomStringUtils.randomNumeric(8);57 queue.setPlaceOrder(oderNumber);58 DeferredResult result=new DeferredResult<>();59 deferredResultHolder.getMap().put(oderNumber, result);60 logger.info("主线程返回");61

62 returnresult;63 }64

65 }

queue.java

1 packagecom.cao.web.async;2

3 importorg.slf4j.Logger;4 importorg.slf4j.LoggerFactory;5 importorg.springframework.stereotype.Component;6

7 @Component8 public classQueue {9 privateString placeOrder;10 privateString completeOrder;11

12 private Logger logger=LoggerFactory.getLogger(getClass());13

14 publicString getPlaceOrder() {15 returnplaceOrder;16 }17 public void setPlaceOrder(String placeOrder) throwsException {18 new Thread(() ->{19 logger.info("接到下单请求");20 try{21 Thread.sleep(2000);22 } catch(InterruptedException e) {23 e.printStackTrace();24 }25 //表示处理完成,应用2将结果返回给了completeOrder

26 this.completeOrder =placeOrder;27 logger.info("下单请求处理完毕" +placeOrder);28 }29

30 ).start();31

32 }33 publicString getCompleteOrder() {34 returncompleteOrder;35 }36 public voidsetCompleteOrder(String completeOrder) {37 this.completeOrder =completeOrder;38 }39

40 }

deferredResultHolder.java

1 packagecom.cao.web.async;2

3 importjava.util.HashMap;4 importjava.util.Map;5

6 importorg.springframework.stereotype.Component;7 importorg.springframework.web.context.request.async.DeferredResult;8

9 @Component10 public classDeferredResultHolder {11 //一个是订单号,一个是订单号的处理结果

12 private Map> map=new HashMap<>();13 public Map>getMap(){14 returnmap;15 }16 public void setMap(Map>map) {17 this.map=map;18 }19 }

QueueListener.java

1 packagecom.cao.web.async;2

3 import staticorg.springframework.test.web.servlet.result.MockMvcResultHandlers.log;4

5 importorg.apache.commons.lang.StringUtils;6 importorg.slf4j.Logger;7 importorg.slf4j.LoggerFactory;8 importorg.springframework.beans.factory.annotation.Autowired;9 importorg.springframework.context.ApplicationListener;10 importorg.springframework.context.event.ContextRefreshedEvent;11 importorg.springframework.stereotype.Component;12

13 @Component14 public class QueueListener implements ApplicationListener{15 @Autowired16 privateQueue queue;17

18 @Autowired19 privateDeferredResultHolder deferredResultHolder;20

21 private Logger logger=LoggerFactory.getLogger(getClass());22

23 @Override24 public voidonApplicationEvent(ContextRefreshedEvent event) {25 new Thread(() ->{26 while (true) {27 if(StringUtils.isNotBlank(queue.getCompleteOrder())) {28 String orderNumber =queue.getCompleteOrder();29 logger.info("返回订单处理结果" +orderNumber);30 deferredResultHolder.getMap().get(orderNumber).setResult("place order success");31 queue.setCompleteOrder(null);32 } else{33 try{34 Thread.sleep(100);35 } catch(InterruptedException e) {36 //TODO Auto-generated catch block

37 e.printStackTrace();38 }39 }40 }41 }).start();42

43

44 }45

46

47 }

4.效果

前端效果

a6f28caed41edcc7819dca969e3560fd.png

控制台效果

665d5c608d2d274a89c2acd42c4442a5.png

三:异步线程的配置

1.说明

对于拦截器,与同步的拦截器不一样,仍然需要配置、

2.主要配置

4c539eddc5d8ecec007145f0ca590aca.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值