一:任务

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. PHP use闭包函数

    <?php class Cart { //产品价格 const PRICE_BUTTER = 1.00; const PRICE_MILK = 3.00; const PRICE_EGGS = ...

  2. Android gradle provided、implementation等指令注意点

    其实这类文章博客网上一搜一大堆,但有些地方可能说的不太清楚(都一样的内容,抄袭太严重),这里只是做个精简的总结和一些其他地方没提到的点. 一.Android Studio 3.0开始使用了新的指令,原 ...

  3. aview安装和使用

    一.安装aalibwget https://sourceforge.net/projects/aa-project/files/latest/download?source=files --no-ch ...

  4. STM32L476应用开发之七:流量的PID控制

    在气体分析仪使用过程中,为了力求分析结果的准确性,一般要求通过的气体流量尽可能的稳定.为了保证流量控制的稳定,我们采用PID调节来控制气路阀门的开度. 1.硬件设计 我们采用的流量计为气体质量流量计, ...

  5. restricted 模式及其 使用

    什么是数据库的RESTRICTED 模式 注:以下内容来至:百度知道 --数据库受限模式,在这个模式下只有RESTRICTED SESSION 权限的人才可以登陆,一般用与数据库维护的时候使用. RE ...

  6. LeetCode(105):从前序与中序遍历序列构造二叉树

    Medium! 题目描述: 根据一棵树的前序遍历与中序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inor ...

  7. 【es】创建索引和映射

    参考:http://www.cnblogs.com/sheeva/p/4837881.html 创建索引: curl -XPUT 'http://localhost:9200/some_index' ...

  8. 剑指offer 二叉搜索树和双向链表

    剑指offer 牛客网 二叉搜索树和双向链表 # -*- coding: utf-8 -*- """ Created on Tue Apr 9 18:58:36 2019 ...

  9. PHP Warning: mysqli_connect(): The server requested authentication method unknown to the client [caching_sha2_password] in /usr/local/php/CreateDB.php on line 5

    原因:php还不支持mysql8.0最新的密码加密方式 ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY ' ...

  10. C++ 关于ShowWindow()的疑问

    IDE: Code::Blocks 16.01 操作系统:Windows 7 x64 最初的代码,目的是为了隐藏窗口出现在任务栏上的图标. #include <windows.h> usi ...