jms异步转同步调用实例
思路:
当主线程调用异步方法时,将自己挂起,并把引用交给jms的监听; 当监听收到返回的消息时,处理并唤醒主线程继续执行(可以获取和处理返回的消息) |
Test.java
package com.my.test; public class Test { @org.junit.Test public void testMain() throws InterruptedException { new Main().main(); } public static void main(String[] args) throws InterruptedException { new Main().main(); } } |
Main.java
package com.my.test; public class Main { /** * @param args * @throws InterruptedException */ public void main() throws InterruptedException { System.out.println("发送异步请求..."); // 发送异步请求,使用uuid作为业务标志(由客户端xml传递) String requestXml = "...<nsrsbh>a</nsrsbh><lsh>db348708ebe46648a1c24ea5d98bc16</lsh>..."; // 解析获取流水号uuid String uuid = getUuid(requestXml); JMSMessageMDB ls = new JMSMessageMDB(); // 以流水号作为key,存放主线程对象 ls.putMap(uuid, this); Thread th = new Thread(ls); th.start(); // 传递当前实例引用,开始等待,设置超时,n秒内不返回,自己恢复 System.out.println("开始等待..."); synchronized (this) { this.wait(10 * 60 * 1000); } // 异步处理后,开始继续执行,如:取异步处理的值 System.out.println("主线程开始继续执行..."); // 获取数据库的消息:根据流水号和业务类别获取 String dbMsg = Dao.getMessage(uuid); System.out.println("获取数据库的消息:" + dbMsg); } // 模拟解析并获取流水号 private String getUuid(String mesage) { return mesage.substring(mesage.indexOf("<lsh>") + 5, mesage.indexOf("</lsh>")); } } |
JMSMessageMDB.java
package com.my.test; import java.util.HashMap; import java.util.Map; import java.util.Random; public class JMSMessageMDB implements Runnable { // 存放主线程对象,key为流水号,value为线程对象 private static Map<Object, Object> map = new HashMap<Object, Object>(); /** * 这里模拟异步消息返回 */ @Override public void run() { while (true) { try { // 监听异步消息 onMessage(createJmsMsg()); System.out.println("sleep..."); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 模拟异步消息返回:告诉主线程异步消息已经到来,可以去取了。 * 详细:每过来一个消息,都会根据消息的流水号从map中查找主线程对象,进而通知主线程恢复(notify); * 消息以流水号作为主键存储在数据库中,由主线程去取; * * @param message */ public void onMessage(String message) { // 解析消息获取流水号 String uuid = getUuid(message); // 将消息存库(以流水号作为主键,并保存业务类别) Dao.saveMessage(message); // 通知主线程: Object main = map.get(uuid); if (null != main) { synchronized (main) { System.out.println("notify()"); main.notify(); } // 清除map中此流水号(或者由主线程清除) map.remove(uuid); } } public Object getMap(Object key) { return map.get(key); } public void removeMap(Object key) { map.remove(key); } public void putMap(Object key, Object value) { map.put(key, value); } /** * 模拟解析并获取流水号: * ...<nsrsbh>a</nsrsbh><lsh>db348708ebe46648a1c24ea5d98bc16</lsh>... * * @param mesage * @return */ private String getUuid(String mesage) { return mesage.substring(mesage.indexOf("<lsh>") + 5, mesage.indexOf("</lsh>")); } private String createJmsMsg() { String msg0 = "...<nsrsbh>a</nsrsbh><lsh>db348708ebe46648a1c24ea5d98bc10</lsh>..."; String msg1 = "...<nsrsbh>b</nsrsbh><lsh>db348708ebe46648a1c24ea5d98bc12</lsh>..."; String msg2 = "...<nsrsbh>c</nsrsbh><lsh>db348708ebe46648a1c24ea5d98bc16</lsh>..."; String msg3 = "...<nsrsbh>d</nsrsbh><lsh>db348708ebe46648a1c24ea5d98bc1w</lsh>..."; String msg4 = "...<nsrsbh>e</nsrsbh><lsh>db348708ebe46648a1c24ea5d98bc1q</lsh>..."; String[] msgs = { msg0, msg1, msg2, msg3, msg4 }; return msgs[new Random().nextInt(5)]; } } |
Dao.java
package com.my.test; public class Dao { public static void saveMessage(String message) { System.out.println("save!"); } public static String getMessage(String key) { System.out.println("get message!"); return "Db message"; } } |
备注:
如果是集群部署,jms返回的消息可能会在其他主机上,则当前主机的主线程无法唤醒,并且另一个主机也会有问题(找不到主线程) |
jms异步转同步调用实例的更多相关文章
- dubbo同步调用、异步调用和是否返回结果源码分析和实例
0. dubbo同步调用.异步调用和是否返回结果配置 (1)dubbo默认为同步调用,并且有返回结果. (2)dubbo异步调用配置,设置 async="true",异步调用可以提 ...
- 循序渐进做项目系列(2):最简单的C/S程序——消息异步调用与消息同步调用
上篇博客 循序渐进做项目系列(1):最简单的C/S程序——让服务器来做加法 实现了一个最简单的C/S程序,即让服务器来做加法.当时为了通俗易懂采用了消息异步调用的方式.今天我们要采用消息同步调用的方式 ...
- java三种调用方式(同步调用/回调/异步调用)
1:同步调用:一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用 2:回调:一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口: 3:异步调用:一种类似消息或事件的机制 ...
- 使用 ActiveMQ 实现JMS 异步调用
目录 简介 启动 ActiveMQ 服务器 查看控制台 ActiveMQ 的消息通道 Queue Topic 比较 开发生产者和消费者 开发服务端(消费者) 开发客户端(生产者) 参考 简介 服务之间 ...
- .NET中的async和await关键字使用及Task异步调用实例
其实早在.NET 4.5的时候M$就在.NET中引入了async和await关键字(VB为Async和Await)来简化异步调用的编程模式.我也早就体验过了,现在写一篇日志来记录一下顺便凑日志数量(以 ...
- 委托(delegate)的三种调用方式:同步调用,异步调用,异步回调(转载)
下面为即将被调用的方法: public delegate int AddHandler(int a,int b); public class 加法类 { public static int Add(i ...
- C#“同步调用”、“异步调用”、“异步回调”
本文将主要通过“同步调用”.“异步调用”.“异步回调”三个示例来讲解在用委托执行同一个“加法类”的时候的的区别和利弊. 首先,通过代码定义一个委托和下面三个示例将要调用的方法: ); //模拟该方法运 ...
- 整理 C#(同步调用、异步调用、异步回调)
//闲来无事,巩固同步异步方面的知识,以备后用,特整理如下: class Program { static void Main(string[] args) { //同步调用 会阻塞当前线程,一步一步 ...
- C# 委托的三种调用示例(同步调用 异步调用 异步回调)
首先,通过代码定义一个委托和下面三个示例将要调用的方法: 复制代码 代码如下: public delegate int AddHandler(int a,int b); public class ...
随机推荐
- 两种解决IE6不支持固定定位的方法
有两种让IE6支持position:fixed1.用CSS执行表达式 *{margin:0;padding:0;} * html,* html body{ background-image:url(a ...
- 简单实用的extend对象合并
/** * 合并对象 * 示例:o = extend({ a: 'a' }, o); */ function extend(s, t) { if (!s) { return {}; } if (!s) ...
- 【转】Android Studio开发应用桌面出现两个或多个图标
原文链接:http://blog.csdn.net/jia635/article/details/78259699 解决办法: 查找的是不是自己的AndroidManifest中 多个Activity ...
- 算法笔记_224:夺冠概率模拟(Java)
目录 1 问题描述 2 解决方案 1 问题描述 足球比赛具有一定程度的偶然性,弱队也有战胜强队的可能. 假设有甲.乙.丙.丁四个球队.根据他们过去比赛的成绩,得出每个队与另一个队对阵时取胜的概率表 ...
- C++ 函数返回局部变量的std::move()的适用场景(转)
作者:神奇先生链接:https://www.zhihu.com/question/57048704/answer/151446405来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
- 【HTML5 Canvas】计算元件/显示对象经过Matrix变换后在上级/舞台上的bounds(边界矩形rect)
如上图所示,这样的一个简单矩形,边界矩形是(x:-28, y:-35, width:152, height:128),这是在这个元件/显示对象自己的坐标空间的范围. 那么把这个放到父元件(舞台)中,再 ...
- cocos2d-js 写日志log 查看日志log Android调试查看log
1 输出日志的方式,当然是cc.log了 2 如何查看日志? a)如果小程序可以先在浏览器上跑,例如用chrome,在控制台就可以看到输出的log: b)如果在真机上调试, ...
- 表访问方式---->全表扫描(Full Table Scans, FTS)
全表扫描(Full Table Scans, FTS) 全表扫描是指Oracle在访问目标表里的数据时,会从该表所占用的第一个区(EXTENT)的第一个块(BLOCK)开始扫描,一直扫描到该表的高水位 ...
- ScrollView嵌套EditText联带滑动的解决的方法
本篇文章的相关内容需结合上文:从ScrollView嵌套EditText的滑动事件冲突分析触摸事件的分发机制以及TextView的简要实现和冲突的解决的方法 在说完了怎样解决ScrollView嵌套E ...
- 〖Android〗屏幕触屏事件录制与回放
需求: 不管是做自动化测试的,还是传媒技术的,自动化操作Android App是一种操作需求: 自动化的操作可以节省很多的人力资源投入: 实现: Android UI界面的自动化,通常有两个方法: 1 ...