一:任务

1.任务

  使用Runnable异步处理Rest服务

  使用DefaultResult异步处理Rest服务

  异步处理的配置

2.原理图说明

  

二:Callable进行异步处理

1.程序

  新建一个anysc的包

 package com.cao.web.async;

 import java.util.concurrent.Callable;

 import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
public class AsyncController {
private Logger logger=LoggerFactory.getLogger(getClass()); @RequestMapping("/order")
public Callable<String> order() throws Exception {
logger.info("主线程开始");
//业务逻辑放在副线程中
Callable<String> result=new Callable<String>() { @Override
public String call() throws Exception {
logger.info("副线程开始");
Thread.sleep(5000);
logger.info("副线程返回");
return "success";
} }; logger.info("主线程返回"); return result;
} }

2.效果

  重点关注时间

  

三:使用DeferredResult

1.问题

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

  是写在主线程中的。

  有些场景是不合适的。

  线程间使用DeferredResult沟通起来。

2.场景如下:

  

3.程序

  程序太多,有点复杂

  控制器

 package com.cao.web.async;

 import java.util.concurrent.Callable;

 import org.apache.commons.lang.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult; @RestController
public class AsyncController {
private Logger logger=LoggerFactory.getLogger(getClass());
@Autowired
private Queue queue; @Autowired
private DeferredResultHolder deferredResultHolder; /**
* 主要是验证Callable
* @return
* @throws Exception
*/
@RequestMapping("/order")
public Callable<String> order() throws Exception {
logger.info("主线程开始");
//业务逻辑放在副线程中
Callable<String> result=new Callable<String>() { @Override
public String call() throws Exception {
logger.info("副线程开始");
Thread.sleep(5000);
logger.info("副线程返回");
return "success";
} }; logger.info("主线程返回"); return result;
}
/**
* 主要是验证
* @return
* @throws Exception
*/
@RequestMapping("/newOrder")
public DeferredResult<String> newOrder() throws Exception {
logger.info("主线程开始");
//
String oderNumber=RandomStringUtils.randomNumeric(8);
queue.setPlaceOrder(oderNumber);
DeferredResult<String> result=new DeferredResult<>();
deferredResultHolder.getMap().put(oderNumber, result);
logger.info("主线程返回"); return result;
} }

  queue.java

 package com.cao.web.async;

 import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; @Component
public class Queue {
private String placeOrder;
private String completeOrder; private Logger logger=LoggerFactory.getLogger(getClass()); public String getPlaceOrder() {
return placeOrder;
}
public void setPlaceOrder(String placeOrder) throws Exception {
new Thread(() -> {
logger.info("接到下单请求");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 表示处理完成,应用2将结果返回给了completeOrder
this.completeOrder = placeOrder;
logger.info("下单请求处理完毕" + placeOrder);
} ).start(); }
public String getCompleteOrder() {
return completeOrder;
}
public void setCompleteOrder(String completeOrder) {
this.completeOrder = completeOrder;
} }

  deferredResultHolder.java

 package com.cao.web.async;

 import java.util.HashMap;
import java.util.Map; import org.springframework.stereotype.Component;
import org.springframework.web.context.request.async.DeferredResult; @Component
public class DeferredResultHolder {
//一个是订单号,一个是订单号的处理结果
private Map<String,DeferredResult<String>> map=new HashMap<>();
public Map<String,DeferredResult<String>> getMap(){
return map;
}
public void setMap(Map<String,DeferredResult<String>> map) {
this.map=map;
}
}

  QueueListener.java

 package com.cao.web.async;

 import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.log;

 import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component; @Component
public class QueueListener implements ApplicationListener<ContextRefreshedEvent>{
@Autowired
private Queue queue; @Autowired
private DeferredResultHolder deferredResultHolder; private Logger logger=LoggerFactory.getLogger(getClass()); @Override
public void onApplicationEvent(ContextRefreshedEvent event) {
new Thread(() -> {
while (true) {
if (StringUtils.isNotBlank(queue.getCompleteOrder())) {
String orderNumber = queue.getCompleteOrder();
logger.info("返回订单处理结果" + orderNumber);
deferredResultHolder.getMap().get(orderNumber).setResult("place order success");
queue.setCompleteOrder(null);
} else {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start(); } }

  

4.效果

  前端效果

  

  控制台效果

  

三:异步线程的配置

1.说明

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

2.主要配置

  

010 异步处理Rest服务的更多相关文章

  1. WPF异步调用WCF服务

    wpf调用wcf时,第一次访问总耗时到达几秒,影响界面的用户体验,因此在wpf加载界面和加载数据时采用异步加载,即异步访问wcf服务, 由于是否采用异步加载和服务端无关,仅仅由客户端自己根据需要来选择 ...

  2. Java笔记(十七) 异步任务执行服务

    异步任务执行服务 一.基本原理和概念 一)基本接口 1)Runnable和Callable:表示要执行的异步任务. 2)Executor和ExecutorService:表示执行服务. 3)Futur ...

  3. 使用kendynet构建异步redis访问服务

    使用kendynet构建异步redis访问服务 最近开始在kendynet上开发手游服务端,游戏类型是生存挑战类的,要存储的数据结构和类型都比较简单,于是选择了用redis做存储,数据类型使用stri ...

  4. Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务、WCF消息头添加安全验证Token

    原文:Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务.WCF消息头添加安全验证Token 为什么选择wcf?   因为好像wcf和wpf就是哥俩,,, 为什么选择异步 ...

  5. mvc路由引起异步调用web服务的问题

    从一篇blog得知使用脚本可以异步调用Web服务,觉得很新鲜,因为自己很少用到Web服务,所以决定写一写看看什么效果. 首先在UI项目(我使用的是MVC4.0)里创建一个Web服务. 添加Web服务后 ...

  6. Silverlight中异步调用WCF服务,传入回调函数

    以前学的ASP.NET,调用的都是同步方法,同步方法的好处就是,一步一步走,完成这步才会走下一步.然而,WCF使用的都是异步方法,调用之后不管有没有获得结果就直接往下走,最可恶的是异步函数都是Void ...

  7. 多线程编程学习笔记——异步调用WCF服务

    接上文 多线程编程学习笔记——使用异步IO 接上文 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端 接上文 多线程编程学习笔记——异步操作数据库 本示例描述了如何创建一个WCF服务,并宿主 ...

  8. Java编程的逻辑 (77) - 异步任务执行服务

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  9. 25.C# 异步调用Web服务

    1.创建Web服务 1.1VS新建ASP.Net空Web应用程序 1.2添加Web服务新建项 1.3添加GetWeather方法和相关类 using System; using System.Coll ...

随机推荐

  1. appium+java (六) 手机chrome浏览器操作

    一.前言 早之前写过一段时间的appium for native app(即原生app脚本),但尴尬的是从未写过类似的文章,后期有时间我会陆续接着写,近一阶段有时间又把appium捡起来了,由于公司产 ...

  2. C#遍历指定文件夹中的所有文件(转)

    C#遍历指定文件夹中的所有文件 DirectoryInfo TheFolder=new DirectoryInfo(folderFullName);//遍历文件夹foreach(DirectoryIn ...

  3. mysql 定期删除表中无用数据

    MySQL5.1.x版本中引入了一项新特性EVENT,定期执行某些事物,这可以帮助我们实现定期执行某个小功能,不在依赖代码去实现. 我现在有一张表,这张表中的数据有个特点,每天都会有大量数据插入,但是 ...

  4. swift 学习- 13 -- 下标

    // 下标 可以定义在 类, 结构体, 和 枚举 中, 是访问集合, 列表或 序列中元素的快捷方式, 可以使用下标的索引, 设置 和 获取值, 而不需要再调用对应的存取方法, 举例来说, 用下标访问一 ...

  5. Modbus库开发笔记:Modbus ASCII Master开发

    这一节我们来封装Modbus ASCII Master应用,Modbus ASCII主站的开发与RTU主站的开发是一致的.同样的我们也不是做具体的应用,而是实现ASCII主站的基本功能.我们将ASCI ...

  6. RianbowDesign

    换了很多个名字,最后换成这个. 主要考虑把自己所学的.所经历的都结合到一起,用这种方式来保持热情. 算是一个设计网站,管理咨询,游戏设计,平面logo之类,想最多地攘括到里边.就像自己不确定的主业一样 ...

  7. Oracle12c Data Guard搭建手册

    Oracle12c Data Guard搭建手册 注:本文来源: 红黑联盟 < Oracle12c Data Guard搭建手册 > Oracle 12c 的DataGuard 是在CDB ...

  8. follow

    public function follow(Request $request, FeedModel $model, FeedRepository $repository) { if (is_null ...

  9. log4j2的log输出到tomcat/logs目录下及使用(转)

    原文链接:http://blog.csdn.net/honghailiang888/article/details/50370252 原文作者:  Herman-Hong 一.环境配置 log4j2. ...

  10. 论文阅读笔记十六:DeconvNet:Learning Deconvolution Network for Semantic Segmentation(ICCV2015)

    论文源址:https://arxiv.org/abs/1505.04366 tensorflow代码:https://github.com/fabianbormann/Tensorflow-Decon ...