zookeeper的学习(一):实现分布式队列queue

算法流程图:
这里写图片描述

核心方法的简要概述:

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);

            }

        }
    }




}

=========================极客学院学习笔记==============================

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值