、队列中提供入队方法offer( T ), 出队方法 poll().
首先初始化参数
protected final ZooKeeper zkClient;
//queue节点
protected final String root;
//顺序节点前缀
protected static final String Node_NAME="n_";
//root队列跟节点
public SimpleDistributedQueue(ZooKeeper zkClient, String root) {
this.zkClient = zkClient;
this.root = root;
}
offer()方法的实现
public boolean offer(T element) throws Exception {
//1拼接顺序节点路径
String nodeFullPath=root.concat("/").concat(Node_NAME);
try {
//以对象流输出到内存,获取byte[]内容
ByteArrayOutputStream bos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(element);
oos.flush();
//2.创建持久顺序节点
zkClient. create(nodeFullPath,bos.toByteArray(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
}catch (KeeperException.NoNodeException e){
//如果没有跟节点就创建跟节点
zkClient.create(root,"".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
//重新调用offer操作
offer(element);
}
catch (Exception e) {
throw new RuntimeException(e);
}
return true;
}
Poll()方法的实现
public T poll() throws Exception{
try {
//1.获取所有顺序节点
List<String>list=zkClient.getChildren(root,false);
if (list.size()==0){
return null;
}
//2.排序
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return getNodeNumber(o1,Node_NAME).compareTo(getNodeNumber(o2,Node_NAME));
}
});
//3.循环每个顺序节点名
for (String nodeName:list){
//构造出顺序节点的完整路径
String nodeFullPath=root.concat("/").concat(nodeName);
try {
//4.读取顺序节点内容
Stat stat=new Stat();
byte[] content=zkClient.getData(nodeFullPath,false,stat);
//5.删除顺序节点
zkClient.delete(nodeFullPath,zkClient.exists(nodeFullPath,true).getVersion());
ByteArrayInputStream bis= new ByteArrayInputStream(content);
ObjectInputStream oos=new ObjectInputStream(bis);
//6.返回此节点内容
return (T) oos.readObject();
}catch (Exception e){
//ignore由其他客户端把这个顺序节点消费掉
e.printStackTrace();
}
}
}catch (Exception e){
throw new RuntimeException(e);
}
return null;
}
获取字节上数字序号
private String getNodeNumber(String str, String nodeName) {
int index=str.lastIndexOf(nodeName);
if(index>=0){
index+=Node_NAME.length();
return index<=str.length() ? str.substring(index) : "";
}
return str;
}
测试:存数据
ZkHelper zkHelper=new ZkHelper();
ZooKeeper zkClient=zkHelper.connect();
final SimpleDistributedQueue<Order> queue=new SimpleDistributedQueue<>(zkClient,"/Queue");
//生产线程
new Thread(new ProducerThread(queue)).start();
测试:设置多个消费者一个生产者,消费的速度大于生产,供不应求
ZkHelper zkHelper=new ZkHelper();
ZooKeeper zkClient=zkHelper.connect();
final SimpleDistributedQueue<Order> queue=new SimpleDistributedQueue<>(zkClient,"/Queue");
//消费线程,offer
new Thread(new ConsumerThread(queue)).start();
//生产线程,poll
new Thread(new ProducerThread(queue)).start();
new Thread(new ConsumerThread(queue)).start();