在ZooKeeper中,所有的同步调用命令,都会有一个相应的异步调用方法。异步调用能在一个单独线程中同时提交更多的命令,也能在一定程度上简化代码实现。

1 异步create方法

如创建zNode的命令create,同步方法的定义是

/**
* @param path 创建节点的路径
* @param data 创建节点的初始值
* @param acl 创建节点的ACL
* @param createMode 创建节点使用永久还是临时模式
* @return 创建节点的真实路径
* @throws KeeperException 服务器返回了非0的错误代码
* @throws KeeperException.InvalidACLException ACL非法或者为空
* @throws InterruptedException 事务被中断
* @throws IllegalArgumentException 路径非法
*/
public String create(final String path,
byte data[],
List<ACL> acl,
CreateMode createMode);

对应的异步调用方法

/**
* create方法的异步调用方法
* @param path 创建节点的路径
* @param data 创建节点的初始值
* @param acl 创建节点的ACL
* @param createMode 创建节点使用永久还是临时模式
* @param cb 包括回调函数的对象
* @param ctx 上下文对象(异步回调时会传递给callback,方便出错时重新调用)
*/
public void create(final String path,
byte data[],
List<ACL> acl,
CreateMode createMode,
StringCallback cb,
Object ctx);

StringCallback的定义

interface StringCallback extends AsyncCallback {
/**
* 处理异步调用的结果
* @param rc 调用的返回码
* @param path 异步调用时的路径参数
* @param ctx 异步调用时的上下文对象
* @param name 实际创建的节点名
* 成功时通常同path相同,除非创建的是sequential节点
*/
public void processResult(int rc,
String path,
Object ctx,
String name);
}

异步调用与同步调用的两个主要区别:

  1. 异步调用没有返回值(void)
  2. 异步调用不抛出异常,异常情况都通过rc参数传递

2 部分rc代码定义

回调函数的第一个参数 rc ,是调用的返回值。ZooKeeper在枚举org.apache.zookeeper.KeeperException.Code中做了定义。从源码中摘出一些我们可能会经常使用的Code

/** 一切安好 */
OK (Ok), /** 服务器连接丢失 */
CONNECTIONLOSS (ConnectionLoss),
/** 操作超时 */
OPERATIONTIMEOUT (OperationTimeout),
/** 参数错误 */
BADARGUMENTS (BadArguments), /** 节点不存在 */
NONODE (NoNode),
/** 临时节点没有子节点 */
NOCHILDRENFOREPHEMERALS (NoChildrenForEphemerals),
/** 节点已经存在 */
NODEEXISTS (NodeExists),
/** 节点有子节点 */
NOTEMPTY (NotEmpty),
/** 会话超时 */
SESSIONEXPIRED (SessionExpired),
/** 请求超时*/
REQUESTTIMEOUT (-122),

3 回调函数的一般用法

下面是一个创建节点的简单例子。注意,ctx参数传递的是data,这个参数会直接传递到callback函数中,这样就可以直接重新调用create命令。

void createNode(String path, byte[] data) {
zooKeeper.create(nodePath, data,
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL,
nodeCreateCallback,
data);
} AsyncCallback.StringCallback nodeCreateCallback = new AsyncCallback.StringCallback() {
public void processResult(int rc, String path, Object ctx, String name) {
switch (KeeperException.Code.get(rc)) {
case OK:
// 创建节点成功
break;
case CONNECTIONLOSS:
// 连接丢失,重新发布命令
createNode(path, ctx);
return;
default:
// 其他异常,抛出或记录异常
KeeperException e = KeeperException.create(KeeperException.Code.get(rc), path);
log.error("create node error", e);
}
}
};

4 异步回调接口定义

ZooKeeper在org.apache.zookeeper.AsyncCallback中定义了几个回调接口

回调接口

说明

适用的异步命令

StatCallback

用于获取节点的状态

void exists()

void setData()

DataCallback

用于获取节点的值和状态

void getData()

void getConfig()

ACLCallback

用于获取节点的ACL信息和状态

void getACL()

ChildrenCallback

用于获取节点的子节点列表

void getChildren()

Children2Callback

用于获取节点的子节点列表和状态

void getChildren()

Create2Callback

用于获取节点的名称和状态

void create()

StringCallback

用于获取节点的名称

void create()

VoidCallback

不返回任何信息

void delete()

void sync()

void removeWatches()

void removeAllWatches()

MultiCallback

用于多命令请求的返回值

void multi()

可以看到,有些异步命令,可以选择使用多个不同的Callback,见下表

异步命令

可选的回调接口

接口说明

void create()

Create2Callback

用于获取节点的名称和状态

StringCallback

用于获取节点的名称

void getChildren()

ChildrenCallback

用于获取节点的子节点列表

Children2Callback

用于获取节点的子节点列表和状态

最新文章

  1. 关于css3
  2. java多线程-线程创建
  3. 写一个 nodejs npm应用 - webhere
  4. jQuery基础--样式篇(2)
  5. android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检索
  6. asp.net MVC4总结
  7. C++与类型转换相关的四个关键字及其特点
  8. warn_alloc():page allocation failure问题分析
  9. C# GDI+编程之绘图
  10. 一、java虚拟机内存区域
  11. 内存分布图,errno
  12. [HDU 1976] Software Version
  13. 在单文件组件中,引入安装模块里的css的2种方式:script中引入、style中引入
  14. Rsync同步设置的一例
  15. GIS矢量数据化简:一种改进的道格拉斯-普克算法以及C++实现
  16. 创建 HelloWorld 项目
  17. [Canvas]走近的女孩
  18. 重塑 data.table
  19. 使用openal与mpg123播放MP3,附带工程文件(转)
  20. php直接输出json格式

热门文章

  1. [leetcode]python 448. Find All Numbers Disappeared in an Array
  2. 基于ng-zorro的ASP.NET ZERO前端实现之代码生成器
  3. 一文了解有趣的位运算(&amp;、|、^、~、&gt;&gt;、&lt;&lt;)
  4. ironic+nova详解
  5. 使用GDAL实现DEM的地貌晕渲图(三)
  6. 我是这样一步步理解--主题模型(Topic Model)、LDA
  7. JavaScript基础学习第六天
  8. 快速清理maven仓库中下载错误的文件
  9. markdown常用方法
  10. 【一些小常识】Linux文件目录的通配符用法/*