算法流程图:
核心方法的简要概述:
1.offer方法
在zookeeper下创建临时顺序节点。
2 poll方法
由于队列的先进先出特性,所以poll方法,就是读取zookeeper队列节点下所有子节点最小number的那个节点,读到数据, 则返回且删除该节点
代码:
package com.zk.queue;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.I0Itec.zkclient.ExceptionUtil;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkNoNodeException;
public class DistributedSimpleQueue<T> {
protected final ZkClient zkClient;
protected final String root;//根节点
protected static final String Node_NAME = "n_";//创建顺序节点的前缀
public DistributedSimpleQueue(ZkClient zkClient, String root) {
this.zkClient = zkClient;
this.root = root;
}
public int size() {
return zkClient.getChildren(root).size();
}
public boolean isEmpty() {
return zkClient.getChildren(root).size() == 0;
}
public boolean offer(T element) throws Exception{
String nodeFullPath = root .concat( "/" ).concat( Node_NAME );
try {
zkClient.createPersistentSequential(nodeFullPath , element);
}catch (ZkNoNodeException e) {
zkClient.createPersistent(root);
offer(element);
} catch (Exception e) {
throw ExceptionUtil.convertToRuntimeException(e);
}
return true;
}
@SuppressWarnings("unchecked")
public T poll() throws Exception {
try {
List<String> list = zkClient.getChildren(root);
if (list.size() == 0) {
return null;
}
Collections.sort(list, new Comparator<String>() {
public int compare(String lhs, String rhs) {
return getNodeNumber(lhs, Node_NAME).compareTo(getNodeNumber(rhs, Node_NAME));
}
});
/* for ( String nodeName : list ){
String nodeFullPath = root.concat("/").concat(nodeName);
try {
T node = (T) zkClient.readData(nodeFullPath);
zkClient.delete(nodeFullPath);
return node;
} catch (ZkNoNodeException e) {
// ignore
}
}*/
try {
String litterNumberNodeName=list.get(0);//获取节点最小数值的节点(队列是先进先出,最小的节点最先创建)
String nodeFullPath=root.concat("/").concat(litterNumberNodeName);
T node = (T) zkClient.readData(nodeFullPath);
zkClient.delete(nodeFullPath);
return node;
} catch (Exception e) {
e.printStackTrace();
}
return null;
} catch (Exception e) {
throw ExceptionUtil.convertToRuntimeException(e);
}
}
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;
}
}
阻塞队列实现:
package com.zk.queue;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.ZkClient;
public class DistributedBlockingQueue<T> extends DistributedSimpleQueue<T>{
public DistributedBlockingQueue(ZkClient zkClient, String root) {
super(zkClient, root);
}
@Override
public T poll() throws Exception {
while (true){
final CountDownLatch latch = new CountDownLatch(1);
final IZkChildListener childListener = new IZkChildListener() {
public void handleChildChange(String parentPath, List<String> currentChilds)
throws Exception {
latch.countDown();
}
};
zkClient.subscribeChildChanges(root, childListener);
try{
T node = super.poll();
if ( node != null ){
return node;
}else{
latch.await();
}
}finally{
zkClient.unsubscribeChildChanges(root, childListener);
}
}
}
}
=========================极客学院学习笔记==============================