一:任务
1.任务
使用Runnable异步处理Rest服务
使用DefaultResult异步处理Rest服务
异步处理的配置
2.原理图说明
二:Callable进行异步处理
1.程序
新建一个anysc的包
1 package com.cao.web.async; 2 3 import java.util.concurrent.Callable; 4 5 import org.slf4j.Logger; 6 import org.slf4j.LoggerFactory; 7 import org.springframework.web.bind.annotation.RequestMapping; 8 import org.springframework.web.bind.annotation.RestController; 9 10 @RestController11 public class AsyncController {12 private Logger logger=LoggerFactory.getLogger(getClass());13 14 @RequestMapping("/order")15 public Callableorder() throws Exception {16 logger.info("主线程开始");17 //业务逻辑放在副线程中18 Callable result=new Callable () {19 20 @Override21 public String call() throws Exception {22 logger.info("副线程开始");23 Thread.sleep(5000);24 logger.info("副线程返回");25 return "success";26 }27 28 };29 30 logger.info("主线程返回");31 32 return result;33 }34 35 }
2.效果
重点关注时间
三:使用DeferredResult
1.问题
方式一是有问题的,因为副线程是需要主线程调用起来的。
是写在主线程中的。
有些场景是不合适的。
线程间使用DeferredResult沟通起来。
2.场景如下:
3.程序
程序太多,有点复杂
控制器
1 package com.cao.web.async; 2 3 import java.util.concurrent.Callable; 4 5 import org.apache.commons.lang.RandomStringUtils; 6 import org.slf4j.Logger; 7 import org.slf4j.LoggerFactory; 8 import org.springframework.beans.factory.annotation.Autowired; 9 import org.springframework.web.bind.annotation.RequestMapping;10 import org.springframework.web.bind.annotation.RestController;11 import org.springframework.web.context.request.async.DeferredResult;12 13 @RestController14 public class AsyncController {15 private Logger logger=LoggerFactory.getLogger(getClass());16 @Autowired17 private Queue queue;18 19 @Autowired20 private DeferredResultHolder deferredResultHolder;21 22 /**23 * 主要是验证Callable24 * @return25 * @throws Exception26 */27 @RequestMapping("/order")28 public Callableorder() throws Exception {29 logger.info("主线程开始");30 //业务逻辑放在副线程中31 Callable result=new Callable () {32 33 @Override34 public String call() throws Exception {35 logger.info("副线程开始");36 Thread.sleep(5000);37 logger.info("副线程返回");38 return "success";39 }40 41 };42 43 logger.info("主线程返回");44 45 return result;46 }47 /**48 * 主要是验证49 * @return50 * @throws Exception51 */52 @RequestMapping("/newOrder")53 public DeferredResult newOrder() throws Exception {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 return result;63 }64 65 }
queue.java
1 package com.cao.web.async; 2 3 import org.slf4j.Logger; 4 import org.slf4j.LoggerFactory; 5 import org.springframework.stereotype.Component; 6 7 @Component 8 public class Queue { 9 private String placeOrder;10 private String completeOrder;11 12 private Logger logger=LoggerFactory.getLogger(getClass());13 14 public String getPlaceOrder() {15 return placeOrder;16 }17 public void setPlaceOrder(String placeOrder) throws Exception {18 new Thread(() -> {19 logger.info("接到下单请求");20 try {21 Thread.sleep(2000);22 } catch (InterruptedException e) {23 e.printStackTrace();24 }25 // 表示处理完成,应用2将结果返回给了completeOrder26 this.completeOrder = placeOrder;27 logger.info("下单请求处理完毕" + placeOrder);28 }29 30 ).start();31 32 }33 public String getCompleteOrder() {34 return completeOrder;35 }36 public void setCompleteOrder(String completeOrder) {37 this.completeOrder = completeOrder;38 }39 40 }
deferredResultHolder.java
1 package com.cao.web.async; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 import org.springframework.stereotype.Component; 7 import org.springframework.web.context.request.async.DeferredResult; 8 9 @Component10 public class DeferredResultHolder {11 //一个是订单号,一个是订单号的处理结果12 private Map> map=new HashMap<>();13 public Map > getMap(){14 return map;15 }16 public void setMap(Map > map) {17 this.map=map;18 }19 }
QueueListener.java
1 package com.cao.web.async; 2 3 import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.log; 4 5 import org.apache.commons.lang.StringUtils; 6 import org.slf4j.Logger; 7 import org.slf4j.LoggerFactory; 8 import org.springframework.beans.factory.annotation.Autowired; 9 import org.springframework.context.ApplicationListener;10 import org.springframework.context.event.ContextRefreshedEvent;11 import org.springframework.stereotype.Component;12 13 @Component14 public class QueueListener implements ApplicationListener{15 @Autowired16 private Queue queue;17 18 @Autowired19 private DeferredResultHolder deferredResultHolder;20 21 private Logger logger=LoggerFactory.getLogger(getClass());22 23 @Override24 public void onApplicationEvent(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 block37 e.printStackTrace();38 }39 }40 }41 }).start();42 43 44 }45 46 47 }
4.效果
前端效果
控制台效果
三:异步线程的配置
1.说明
对于拦截器,与同步的拦截器不一样,仍然需要配置、
2.主要配置