zoukankan      html  css  js  c++  java
  • zk分布式锁-排它锁简单实现-优化版

    package Lock;

    import java.util.Collection;
    import java.util.Collections;
    import java.util.List;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;

    import org.I0Itec.zkclient.IZkChildListener;
    import org.I0Itec.zkclient.IZkDataListener;
    import org.I0Itec.zkclient.ZkClient;

    public class ImproveLock implements Lock{
    private static String ZK_IP_PORT= "192.168.0.137:2181";
    private static String LOCK_NODE = "/lock";
    private ZkClient client = new ZkClient(ZK_IP_PORT);
    private String currentNode = null; //当前节点
    private String beforeNode = null; //前一个节点
    private CountDownLatch cdl = null;

    public ImproveLock(){
    //创建持久节点
    if(!client.exists(LOCK_NODE)){
    client.createPersistent(LOCK_NODE);
    }
    }

    @Override
    public void lock() {
    if(tryLock()){
    return ;
    }
    waitForLock();
    lock();
    }

    private void waitForLock(){
    IZkDataListener listener = new IZkDataListener() {

    @Override
    public void handleDataDeleted(String dataPath) throws Exception {
    if(cdl != null){
    cdl.countDown();
    }
    }

    @Override
    public void handleDataChange(String dataPath, Object data) throws Exception {

    }
    };

    client.subscribeDataChanges(beforeNode, listener);
    if(client.exists(beforeNode)){
    cdl = new CountDownLatch(1);
    try {
    cdl.await();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    client.unsubscribeDataChanges(beforeNode, listener);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {

    }
    @Override
    public boolean tryLock() {
    if(currentNode == null || currentNode.length() == 0){
    currentNode = client.createEphemeralSequential(LOCK_NODE + "/", "lock");
    System.out.println("--------------:" + currentNode);
    }
    //获取所有的子节点
    List<String> children = client.getChildren(LOCK_NODE);
    //子节点排序
    Collections.sort(children);
    if(currentNode.equals(LOCK_NODE + "/" + children.get(0))){
    return true;
    }
    //找当前节点的前一个节点
    int index = Collections.binarySearch(children, currentNode.substring(6));
    if(index > 0){
    index = index - 1;
    }
    beforeNode = LOCK_NODE + "/" + children.get(index);
    return false;
    }
    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
    return false;
    }
    @Override
    public void unlock() {
    client.delete(currentNode);
    }
    @Override
    public Condition newCondition() {
    return null;
    }
    }

    ---------------------test-----

    package Lock;

    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.CountDownLatch;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;

    public class LockTest {
    private static Logger LOG = LoggerFactory.getLogger(LockTest.class);
    private static int count = 10;
    private static CountDownLatch cdl = new CountDownLatch(count);
    public static void main(String[] args) {
    for(int i = 0; i < count;i++){
    new Thread(new Order()).start();
    LOG.error("开启");
    cdl.countDown();
    }
    }

    static class Order implements Runnable{
    //private DistributeLock lock = new DistributeLock();
    private ImproveLock lock = new ImproveLock();
    @Override
    public void run() {
    try {
    cdl.await();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    lock.lock();
    String orderId = GenorderId.genOrderId();

    System.out.println(orderId);
    lock.unlock();
    }

    }

    static class GenorderId{
    private static int index = 0;
    public static String genOrderId(){
    SimpleDateFormat sdf = new SimpleDateFormat("yyyymmddhhmmss|SSS");
    return sdf.format(new Date()) + ++index;
    }
    }

    }

  • 相关阅读:
    JS LeetCode 1423. 可获得的最大点数简单题解
    SpringBoot 学集 (第六章) Docker
    Linux 学记 (第三章)
    Linux 学记 (第二章)
    Linux 学记 (第一章)
    SpringBoot 学集 (第五章) Web开发续
    SpringBoot 学集 (第四章)Web开发
    SpringBoot 学集 (第三章) 日志框架
    SpringBoot 学集 (第二章) 配置文件
    SpringBoot 学集 (第一章)
  • 原文地址:https://www.cnblogs.com/maohuidong/p/8433611.html
Copyright © 2011-2022 走看看