[ZooKeeper]纠正官网的Queue示例

来源:互联网 发布:美工军工基金指数 编辑:程序博客网 时间:2024/05/17 03:56

Queue接口

public interface Queue<E> {boolean produce(E e) throws InterruptedException, QueueException;E consume() throws QueueException, InterruptedException;}


单机版的队列用BlockingDeque或BlockingQueue就能实现

import java.util.concurrent.BlockingDeque;import java.util.concurrent.LinkedBlockingDeque;/** * 单机版的队列 * */public class StandaloneQueue<E> {private BlockingDeque<E> deque;public StandaloneQueue() {deque = new LinkedBlockingDeque<>();}public boolean produce(E e) {return deque.offerLast(e);}public E consume() throws InterruptedException {return deque.takeFirst();}}

分布式版的Queue,对于getData和delete时产生的NONODE异常可以放过

import java.io.IOException;import java.nio.ByteBuffer;import java.util.List;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;import org.apache.zookeeper.CreateMode;import org.apache.zookeeper.KeeperException;import org.apache.zookeeper.WatchedEvent;import org.apache.zookeeper.Watcher;import org.apache.zookeeper.ZooKeeper;import org.apache.zookeeper.KeeperException.Code;import org.apache.zookeeper.ZooDefs.Ids;import org.apache.zookeeper.data.Stat;/** * 分布式的队列 */public class DistributedQueue implements Queue<Integer>, Watcher {private String root;private String queueName;private ZooKeeper zooKeeper;        private Lock lock;          private Condition nodeChildrenChange;  private volatile boolean expired;public DistributedQueue(String address, String root, String queueName) throws QueueException, InterruptedException {this.root = root;this.queueName = queueName;lock = new ReentrantLock();          nodeChildrenChange = lock.newCondition(); try {              zooKeeper = new ZooKeeper(address, 3000, this);          } catch (IOException e) {              throw new QueueException(e);          }                    try {              Stat stat = zooKeeper.exists(root, false);              if (stat == null) {                  zooKeeper.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);              }          } catch (KeeperException e) {              if (e.code() != Code.NODEEXISTS) {                  throw new QueueException(e);              }          } }@Overridepublic boolean produce(Integer i) throws InterruptedException, QueueException {ByteBuffer b = ByteBuffer.allocate(4);b.putInt(i);byte[] value = b.array();try {zooKeeper.create(root + "/" + queueName, value, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);return true;} catch (KeeperException e) {throw new QueueException(e);}}@Overridepublic Integer consume() throws QueueException, InterruptedException {while (!Thread.interrupted() && !expired) {List<String> list;try {list = zooKeeper.getChildren(root, true);} catch (KeeperException e) {throw new QueueException(e);}if (list.isEmpty()) {lock.lock();                  try {                      nodeChildrenChange.await();                  } finally {                      lock.unlock();                  }} else {Integer min = new Integer(list.get(0).substring(7));                for(String s : list){                    Integer tempValue = new Integer(s.substring(7));                    if(tempValue < min) min = tempValue;                }                                String path = root + "/" + queueName + min;                try {byte[] value = zooKeeper.getData(path, false, null);zooKeeper.delete(path, 0);ByteBuffer buffer = ByteBuffer.wrap(value);return buffer.getInt();} catch (KeeperException e) {if (e.code() != Code.NONODE) {throw new QueueException(e);}// 数据已经被别人取走}}}throw new QueueException("interruped or expired");}@Overridepublic void process(WatchedEvent event) {if (event.getType() == Watcher.Event.EventType.None) {              if (event.getState() == Watcher.Event.KeeperState.Expired) {                  expired = true;                  try {                      zooKeeper.close();                  } catch (InterruptedException e) {                      // do nothing;                  }              }          } else if (event.getType() == Watcher.Event.EventType.NodeChildrenChanged) {              lock.lock();              try {                  nodeChildrenChange.signalAll();              } finally {                  lock.unlock();              }          }}}


0 0
原创粉丝点击