一、设计
例如,使用路径为/queue的znode下的节点表示队列中的元素。/queue下的节点都是顺序持久化znode。这些znode名字的后缀数字表示了对应队列元素在队列中的位置。znode名字后缀数字越小,对应队列元素在队列中的位置越靠前。例如:
二、主要方法
- 入队
在一个死循环里面,调用zookeeper.create方法,创建PERSISTENT_SEQUENTIAL模式的数据,其前缀为qn- - 出队
在不更改队列的条件下,出队队列快照中的数据。注意的是getData的成功执行并不意味着出队成功,原因是可能别其他客户端给出队了。如果读取到了队列为空的状态的话,会抛出异常
NoSuchElementException。也正是因为Since other clients are remove()ing and take()ing nodes concurrently,所以把操作都是放于一个死循环(while(true))中执行。 - 删除
与element()不同的地方为调用了一次删除操作:zookeeper.delete(path, -1); -
出队并移除,并且确保能够返回并移除成功。
通过一个LatchChildWatcher来监控目录数据的变动。并确保每次能出队一个数据。与与element()方法最明显的不同之处为,不会抛出异常NoSuchElementException。
三、执行测试
通过类org.apache.zookeeper.recipes.queue.DistributedQueueTest类执行测试案例。
因为此类继承自org.apache.zookeeper.test.ClientBase,在ClientBase类中,有几个重要的初始化变量需要配置,如下图:
如果变量BASETEST取值与系统参数"build.test.dir",所以在IDE中,需要 设置测试运行的JVM运行参数 -Dbuild.test.dir=D:/study/zookeeper/source/dataDir,
否则,会报以下错误:
启动ZookeeperServerMain,并执行测试案例: