首先说说ami 和amd 的区别(以下为个人见解,仅供参考。如有疑问欢迎提出来)

ami (异步方法调用):

仅仅基于ice 的同步方式扩展了异步的扩展方式,其他理念改动不大,使用起来好理解,但是服务端依赖异步线程数量配置,线程数量如果爆仓,据文档描述后面的请求全部都会丢失。

amd(异步分派方法):

优化ami关于线程数限制的缺点。(摘自Ice中文教程

在使用 AMD 时,服务器可以接收一个请求,然后挂起其处理,
以尽快释放分派线程。当处理恢复、结果已得出时,服务器要使用 Ice run
time 提供的回调对象,显式地发送响应。
用实际的术语说, AMD 操作通常会把请求数据 (也就是,回调对象和
操作参数)放入队列 ,供应用的某个线程 (或线程池)随后处理用。这
样,服务器就使分派线程的使用率降到了最低限度,能够高效地支持数千
并发客户。
另外, AMD 还可用于需要在完成了客户的请求之后继续进行处理的操
作。为了使客户的延迟降到最低限度,操作在返回结果后,仍留在分派线
程中,继续用分派线程执行其他工作。

)。就是说每次服务器吧每次请求都放在线程池中挂起,直至开始处理这个请求。并且在将结果返回个客户端后还可以接着执行其他工作。比如一些扫尾工作不用在返回客户端结果前做,可以之后做,明显可以降低客户等待时间。

开始上代码:

ami异步方法调用:

1、先定义slice接口

["ami"]interface TestAnys1{//接口内的方法全部都是ami模式string getAnysString();};

2、服务端继承_TestAnys1Disp类,实现处理方法

/*** ami服务端实现类* @author laobiao**/
public class TestAnys1I extends _TestAnys1Disp{@Overridepublic String getAnysString(Current __current) {try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch block
                e.printStackTrace();}System.out.println("的撒旦撒");return "返回结果字符串";}}

3、简单的服务发布

package testIceAnysServer.ami;public class Server extends Ice.Application {public static void main(String[] args) {//实例化服务Server app = new Server();//启动服务(这里执行了run方法)int status=app.main("Server", args);System.exit(status);}@Overridepublic int run(String[] args) {Ice.ObjectAdapter adapter = communicator().createObjectAdapterWithEndpoints("AnysAmi", "default -p 8778");Ice.Object servant = new TestAnys1I();adapter.add(servant, Ice.Util.stringToIdentity("testAmi"));adapter.activate();communicator().waitForShutdown();return 0;}}

到此服务端工作完成

4、客户端实现异步回调方法  AMI_TestAnys1_getAnysString 为ICE自动生成的接口回调抽象类(AMI_slice定义的接口名_接口中的方法名)

package testIceAnysServer.ami;import Ice.LocalException;
import model.AMI_TestAnys1_getAnysString;
/*** Ami客户端回调* @author laobiao**/
public class TestAnys1_interpolateI extends AMI_TestAnys1_getAnysString{/**  * 无异常返回结果回调   */@Overridepublic void ice_response(String __ret) {System.out.println("客户端收到回调信息:"+__ret);}
/**  * 异常返回结果回调   */
@Override public void ice_exception(LocalException ex) { System.out.println("客户端收到异常:"+ex.getMessage()); } }

5、简单的客户端请求请求数据方式

package testIceAnysServer.ami;import model.TestAnys1Prx;
import model.TestAnys1PrxHelper;public class Client {public static void main(String[] args) {int status = 0;// 定义通信器Ice.Communicator ic = null;try {// Create a communicator// 实例化通信器ic = Ice.Util.initialize(args);// Create a proxy for the root directory// 实例化通信代理Ice.ObjectPrx base = ic.stringToProxy("testAmi:default -p 8778");if (base == null)throw new RuntimeException("Cannot create proxy");//获取代理TestAnys1Prx TestAnys1I = TestAnys1PrxHelper.checkedCast(base);if (TestAnys1I == null)throw new RuntimeException("Invalid proxy");//定义回调方式TestAnys1_interpolateI zz=new TestAnys1_interpolateI();//注入回调方式,请求数据
            TestAnys1I.begin_getAnysString(zz);System.out.println("完成");} catch (Ice.LocalException e) {e.printStackTrace();status = 1;} catch (Exception e) {System.err.println(e.getMessage());status = 1;} finally {// Clean up//
            if (ic != null)ic.destroy();}System.exit(status);}}

至此客户端完成。

输出打印结果应该为:

完成
收到回调信息:返回结果字符串

amd异步分派方法:

1、定义slice:

["amd"]interface TestAnys2{//当前接口下所有方法都是amd模式string getAnysString();};

2、服务端继承 _TestAnys2Disp 抽象类,实现接口方法处理

package testIceAnysServer.amd;import Ice.Current;
import model.AMD_TestAnys2_getAnysString;
import model._TestAnys2Disp;
/*** 服务端AMD模式处理方法* @author laobiao**/
public class TestAnys2 extends _TestAnys2Disp{@Overridepublic void getAnysString_async(AMD_TestAnys2_getAnysString __cb, Current __current) {System.out.println("服务端执行方法");__cb.ice_response("返回结果字符串");//这里已经将结果返回给客户端了
        System.out.println("开始扫尾工作");//..............
        }}

3、服务端开启

package testIceAnysServer.amd;public class Server extends Ice.Application {public static void main(String[] args) {//实例化服务Server app = new Server();//启动服务(这里执行了run方法)int status=app.main("Server", args);System.exit(status);}@Overridepublic int run(String[] args) {Ice.ObjectAdapter adapter = communicator().createObjectAdapterWithEndpoints("AnysAmd", "default -p 8778");Ice.Object servant = new TestAnys2();adapter.add(servant, Ice.Util.stringToIdentity("testAmd"));adapter.activate();communicator().waitForShutdown();return 0;}}

至此服务端代码完成 可以开启服务了

4、客户端 继承抽象类 Callback_TestAnys2_getAnysString (Callback_slice定义的接口名_接口方法) 实现回调处理方法

package testIceAnysServer.amd;import Ice.LocalException;
import model.AMD_TestAnys2_getAnysString;
import model.Callback_TestAnys2_getAnysString;/*** 客户端AMD模式回调方法* @author laobiao**/
public class TestAnys2_interpolatel extends Callback_TestAnys2_getAnysString{//无异常回调处理方式@Overridepublic void response(String __ret) {try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch block
            e.printStackTrace();}System.out.println("收到回调信息:"+__ret);}//发生异常结果回调处理方式@Overridepublic void exception(LocalException __ex) {System.out.println("收到异常:"+__ex.getMessage());            }}

5、客户端启动并执行方法

package testIceAnysServer.amd;import Ice.LocalException;
import model.Callback_TestAnys2_getAnysString;
import model.TestAnys1Prx;
import model.TestAnys1PrxHelper;
import model.TestAnys2Prx;
import model.TestAnys2PrxHelper;public class Client {public static void main(String[] args) {int status = 0;// 定义通信器Ice.Communicator ic = null;try {// Create a communicator// 实例化通信器ic = Ice.Util.initialize(args);// 实例化通信代理Ice.ObjectPrx base = ic.stringToProxy("testAmd:default -p 8778");if (base == null)throw new RuntimeException("Cannot create proxy");TestAnys2Prx TestAnys2 = TestAnys2PrxHelper.checkedCast(base);if (TestAnys2 == null)throw new RuntimeException("Invalid proxy");TestAnys2.begin_getAnysString(new TestAnys2_interpolatel());//System.out.println(s);System.out.println("完成");} catch (Ice.LocalException e) {e.printStackTrace();status = 1;} catch (Exception e) {System.err.println(e.getMessage());status = 1;} finally {// Clean up//
            if (ic != null)ic.destroy();}System.exit(status);}}

至此客户端编码工作完成。

执行客户端输出应该为:

完成
收到回调信息:返回结果字符串

思考:

  在上述两种模式中,我发现使用ice异步的两种模式流程很相似。都是在服务端实现业务处理方法,在客户端实现回调方法。但是他们代码层面来说一种服务端直接实现业务的返回方法(ami  直接renturn结果)。另一种直接使用返回方法而是抓住持有返回方法的对象在需要的时候再返回结果(amd),这就给我们提供能更多的扩展方式。

资料参考:Ice_中文教程

转载于:https://www.cnblogs.com/laobiao/p/7226835.html

ZeroC ICE java异步实现方式(ami/amd)相关推荐

  1. Java 异步编程 (5 种异步实现方式详解)

    同步操作如果遇到一个耗时的方法,需要阻塞等待,那么我们有没有办法解决呢?让它异步执行,下面我会详解异步及实现 @mikechen 目录 什么是异步? 一.线程异步 二.Future异步 三.Compl ...

  2. Java构建工具, ZeroC ICE, word2vec

    https://antkillerfarm.github.io/ Java构建工具 构建工具的意义在于,提供一种独立于IDE的软件构建方式.而且通常来说,构建工具更适合特大项目的构建.比如,即使是以功 ...

  3. java异步处理同步化_java 异步查询转同步多种实现方式:循环等待,CountDownLatch,Spring EventListener,超时处理和空循环性能优化...

    异步转同步 业务需求 有些接口查询反馈结果是异步返回的,无法立刻获取查询结果. 正常处理逻辑 触发异步操作,然后传递一个唯一标识. 等到异步结果返回,根据传入的唯一标识,匹配此次结果. 如何转换为同步 ...

  4. Java异步非阻塞编程的几种方式

    简介: Java异步非阻塞编程的几种方式 一. 从一个同步的Http调用说起 一个很简单的业务逻辑,其他后端服务提供了一个接口,我们需要通过接口调用,获取到响应的数据. 逆地理接口:通过经纬度获取这个 ...

  5. Java异步调用的几种方式

    一.通过创建新线程 二.通过线程池 三.通过@Async注解 四.通过CompletableFuture 日常开发中,会经常遇到说,前台调服务,然后触发一个比较耗时的异步服务,且不用等异步任务的处理结 ...

  6. ZeroC Ice 暂记

    摘自: http://weibo.com/p/1001603869896789339575 原文地址: http://www.oschina.net/question/865233_242146 吴治 ...

  7. Ice笔记---异步程序设计demo

    最近学习了异步通信这一章:异步包括服务端的异步分派(AMD)以及客户端的异步调用(AMI). 下面介绍一下如何实现简单的异步通信(主要实现了客户端的异步调用,AMD暂未体现): 1.首先编写Ice文件 ...

  8. 一文带你彻底了解Java异步

    随着RxJava.Reactor等异步框架的流行,异步编程受到了越来越多的关注,尤其是在IO密集型的业务场景中,相比传统的同步开发模式,异步编程的优势越来越明显. 那到底什么是异步编程?异步化真正的好 ...

  9. 阿里技术专家加多:Java异步编程实战之基于JDK中的Future实现异步编程 | 文末赠书...

    正文共:14244 字 8 图 预计阅读时间: 36 分钟 本节内容摘自<Java异步编程实战>中的一小节. 一.前言 本节主要讲解如何使用JDK中的Future实现异步编程,这包含如何使 ...

最新文章

  1. C++中类的多态与虚函数的使用
  2. python深度学习环境支撑列表 各版本对应关系,Keras,TensorFlow,pytorch ,caffe等。
  3. Pycharm快捷键大全(windows + Mac)
  4. Linux内核学习笔记五——中断推后处理机制
  5. Git(8)-- 撤消操作(git commit --amend、git reset 和 git checkout 命令详解)
  6. nlu 意图识别_在NLU中,您无视危险的意图
  7. 读书笔记:Hadoop权威指南 简介
  8. Python基础之爬取豆瓣图书信息
  9. C#毕业设计——基于C#+asp.net+sqlserver的交通信息网上查询系统设计与实现(毕业论文+程序源码)——交通信息网上查询系统
  10. Linux mkdir、touch、mv、cp等命令的介绍与使用
  11. word 条件多项式公式对齐
  12. 2023年美国大学生数学建模竞赛(春季赛)
  13. Springboot2中文件上传报java.io.FileNotFoundException: C:\Users\WIzarder\AppData\Local\Temp\tomcat.8080.589
  14. 三星s5html查看器,三星S5玩机技巧之系统精简篇
  15. 【LeetCode】1405-最长快乐字符串
  16. C++之sync_with_stdio(false)
  17. c++ primer读书笔记-第十四章 重载操作符与转换
  18. StrongShop 开源商城 跨境电商独立站的理想选择
  19. 2020百度云智峰会举行,CTO王海峰与浦发银行、明阳智慧能源登台央视“对话”成亮点
  20. 电销外呼系统怎么选择

热门文章

  1. Uva 11542 乘积是平方数
  2. 1.2.3 TCP/IP参考模型和五层参考模型
  3. CCS5.5 中报错 Does not match the target type,not loaded 的一种情况
  4. vivado使用自带IP核和创建自己定义的IP核
  5. Xilinx FPGA部分重配置操作流程
  6. python 虚拟环境就两句话整那么多没用的
  7. 从源码分析DEARGUI之键盘鼠标事件监控
  8. TCP的三次握手与四次挥手(详解+动图)
  9. 平面上给定n条线段,找出一个点,使这个点到这n条线段的距离和最小。
  10. 如何解决ORA-12547错误!