zoukankan      html  css  js  c++  java
  • 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返回的消息可能会在其他主机上,则当前主机的主线程无法唤醒,并且另一个主机也会有问题(找不到主线程)

  • 相关阅读:
    [ARC 102D]All Your Paths are Different Lengths
    [NOI 2016] 优秀的拆分
    [TJOI 2015] 线性代数
    [LUOGU 4717] 快速沃尔什变换
    [NOI 2006] 最大获利
    Javascript继承机制的设计
    必应输入法产品分析
    你不得不知道的HTML5的新型标签
    Mobile Web
    10行代码爬取网页
  • 原文地址:https://www.cnblogs.com/qqzy168/p/3410752.html
Copyright © 2011-2022 走看看