首先说说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{ @Override
public 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); } @Override
public 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{
  /**
  * 无异常返回结果回调 
  */
@Override
public 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{ @Override
public 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); } @Override
public 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{   //无异常回调处理方式
@Override
public void response(String __ret) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("收到回调信息:"+__ret); }
  //发生异常结果回调处理方式
@Override
public 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_中文教程

ZeroC ICE java异步实现方式(ami/amd)的更多相关文章

  1. ZeroC ICE的远程调用框架 AMI与AMD -Why?

    在Ice有两种异步使用的方式,AMI和AMD.AMI是异步方法调用,AMD是异步方法调度(分派).前者用在代理端,后者用在饲服实现端. AMI其实就是在代理端,使用Future机制进行异步调用,而不阻 ...

  2. ZeroC ICE的远程调用框架 Slice如何帮助我们进行Ice异步编程(AMI,AMD)

    Slice最大的用处就是为我们使用Ice进行编程,代劳绝大部分的重复性代码,并提供一些帮助性的框架代码,如用于AMI和AMD方式进行异步编程的回调框架. 当Slice不为我们生成代码时,我们仍然可以按 ...

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

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

  4. ICE异步程序设计-----AMI/AMD

    1 简介 AMI 异步方法调用(AMI) 这个术语描述的是客户端的异步编程模型支持. 如果你使用AMI 发出远地调用,在Ice run time 等待答复的同时,发出调用的线程不会阻塞.相反,发出调用 ...

  5. ZEROC ICE 跨平台间程序调用 java版

    前言: 本来建博客是为了和大家分享一些前端的开发经验和心得呢,但是阴差阳错,第一篇技术博客确实关于跨平台,跨语言服务端调用的解决方案---ZEROC ICE. 最近一个项目涉及到java.python ...

  6. 开发zeroc ice应用入门(java开发ice应用,python开发ice应用,java与python结合开发ice服务)

    ice作为一种rpc框架,为主流平台设计,包括Windows和Linux,支持广泛的语言,包括C++,Java,C#(和其他.Net的语言,例如Visual Basic),Python,Ruby,PH ...

  7. Ubuntu16.04下ZeroC ICE的安装与使用示例(Qt C++ 和 Java)

    项目需求:在Ubuntu16.04系统下安装并使用ICEgrid 3.7进行c++和Java Springboot开发环境的通信,下面逐一介绍各个步骤的详解: 一:Ice Lib的安装 参考官网地址: ...

  8. ZeroC ICE的远程调用框架 AMD

    继上一篇<ZeroC ICE的远程调用框架>,本篇再来说其中的AMD.(本篇需要重写) 当在ice文件中声明某个接口方法Method为["amd"]后,接口方法在stu ...

  9. Java 异步编程的几种方式

    前言 异步编程是让程序并发运行的一种手段.它允许多个事情同时发生,当程序调用需要长时间运行的方法时,它不会阻塞当前的执行流程,程序可以继续运行,当方法执行完成时通知给主线程根据需要获取其执行结果或者失 ...

随机推荐

  1. 网络初级篇之STP(实验验证)

    一.根桥的选举. 1.优先级相等时. (图1-1) (图1-2) 在上面1-1图中,已经标出桥的mac地址,桥的优先级为默认优先级(缺省:32768).任意一端口抓包,查看STP数据包内包含的信息,根 ...

  2. IntelliJ IDEA 如何设置代码提示和代码模板

    在编写java代码时如何设置不分大小写提示和设置快捷输出模板代码 首先设置不分大小写,settings-Editor-General-CodeCompletion 将红框的Match case取消打勾 ...

  3. 热门前沿知识相关面试问题-android插件化面试问题讲解

    插件化由来: 65536/64K[技术层面上]随着代码越来越大,业务逻辑越来繁杂,所以很容易达到一个65536的天花板,其65536指的是整个项目中的方法总数如果达到这个数量时则不无法创建新的方法了, ...

  4. openssl数据加密

    一.openssl简介 openssl是最著名的开源SSL,其用 C 实现,被广泛应用在基于TCP/Socket的网络程序中. OpenSSL:开源项目 三个组件:openssl: 多用途的命令行工具 ...

  5. ChromePassword

    # -*- coding: utf-8 -*- 2# @Author : pwf 3 4# @Date : 2019/5/18 22:53 5# Software : PyCharm 6# versi ...

  6. java 获取随机数的方法

    方法一: (数据类型)(最小值 + Math.random()*(最大值-最小值+1) ); 示例: (int)(1+Math.random()*(10-1+1)): 获取int类型 1-10的随机数 ...

  7. IDEA 使用LiveEdit插件

    第一步: 第二步: 第三步: 第四步: 等待下载完成 第五步: 第六步: 第七步: 配置tomcat时注意选择chrome浏览器,并勾选右边的多选框 完成之后,就可以启动项目了,然后可以改变html代 ...

  8. SparkSQL之UDF使用

    package cn.piesat.test import org.apache.spark.sql.SparkSession import scala.collection.mutable.Arra ...

  9. gdb插件gef安装爬坑

    0x00: gdb是linux下的调试利器,但无奈界面不太友好,所以需要一些辅助插件. 0x01:关于插件选择 之前我一直使用的是pead,之前了解到还有个插件gef,因为gef支持多构架,而且hea ...

  10. Xshell安装教程及Xshell安装程序集组件时出错的解决方法

    部分小伙伴在安装Xshell的时候可能会遇到这个问题:“Xshell5安装程序集组件{0D7E67F6-1A6A-3A26-AF95-B8E83DDCCC3F}时出错.HRESULT0x80070BC ...