您当前的位置: 首页 >  分布式

java持续实践

暂无认证

  • 1浏览

    0关注

    746博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

zk基于顺序节点实现分布式锁demo

java持续实践 发布时间:2021-06-01 06:54:28 ,浏览量:1

笔记来源: Java工程师面试突击专栏 https://apppukyptrl1086.pc.xiaoe-tech.com/detail/p_5d3114935b4d7_CEcL8yMS/6

public class ZooKeeperDistributedLock implements Watcher{
	
    private ZooKeeper zk;
    private String locksRoot= "/locks";
    private String productId;
    private String waitNode;
    private String lockNode;
    private CountDownLatch latch;
    private CountDownLatch connectedLatch = new CountDownLatch(1);
private int sessionTimeout = 30000; 

    public ZooKeeperDistributedLock(String productId){
        this.productId = productId;
         try {
	   String address = "192.168.31.187:2181,192.168.31.19:2181,192.168.31.227:2181";
            zk = new ZooKeeper(address, sessionTimeout, this);
            connectedLatch.await();
        } catch (IOException e) {
            throw new LockException(e);
        } catch (KeeperException e) {
            throw new LockException(e);
        } catch (InterruptedException e) {
            throw new LockException(e);
        }
    }
	
	// 锁释放后, 回调此方法
    public void process(WatchedEvent event) {
        if(event.getState()==KeeperState.SyncConnected){
        // 执行countDown ,  让线程进入可运行的状态
            connectedLatch.countDown();
            return;
        }

        if(this.latch != null) {  
            this.latch.countDown(); 
        }
    }

    public void acquireDistributedLock() {   
        try {
            if(this.tryLock()){
                return;
            }
            else{
                waitForLock(waitNode, sessionTimeout);
            }
        } catch (KeeperException e) {
            throw new LockException(e);
        } catch (InterruptedException e) {
            throw new LockException(e);
        } 
}

    public boolean tryLock() {
        try {
 		// 传入进去的locksRoot + “/” + productId
		// 假设productId代表了一个商品id,比如说1
		// locksRoot = locks
		// /locks/10000000000,/locks/10000000001,/locks/10000000002
            lockNode = zk.create(locksRoot + "/" + productId, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); // 尝试去创建临时顺序节点
   
            // 看看刚创建的节点是不是最小的节点
	 	// locks:10000000000,10000000001,10000000002
            List locks = zk.getChildren(locksRoot, false);
            // 排序  从小到大 
            Collections.sort(locks);
			
			// 判断是不是第一个节点
            if(lockNode.equals(locksRoot+"/"+ locks.get(0))){
                //如果是最小的节点,则表示取得锁
                return true;
            }
	
            //如果不是最小的节点,找到比自己小1的节点
	  int previousLockIndex = -1;
            for(int i = 0; i             
关注
打赏
1658054974
查看更多评论
0.0403s