zookeeper-實現分佈式鎖(6)

Zookeeper實現分佈式鎖

  • 原生API實現
1.每個客戶端往/Locks下創建臨時有序節點/Locks/Lock 000000001 
2.客戶端取得/Locks下子節點,並進行排序,判斷排在最前面的是否爲自己,如果自己的鎖節點在第一位代表獲取鎖成功 
3.如果自己的鎖節點不在第一位,則監聽自己前一位的鎖節點。例如,自己鎖節點 Lock 000000001 
4.當前一位鎖節點(Lock 000000002)的邏輯 
5.監聽客戶端重新執行第2步邏輯,判斷自己是否獲得了鎖
/**
 * @Author: zxx
 * @Date: 2020/3/30 21:43
 * @Description: 生成唯一ID
 */
public class ZKUniqueID implements Watcher{
    // 計數器對象
    public static CountDownLatch countDownLatch=new CountDownLatch(1);
    // 連接對象
    public static ZooKeeper zooKeeper;

    private String IP = "192.168.21.141:2181";

    // 用戶生成序號的節點
    String defaultPath = "/uniqueId";

    public ZKUniqueID() throws Exception {
        zooKeeper = new ZooKeeper(IP, 6000, this);
        countDownLatch.await();
    }

    public void process(WatchedEvent watchedEvent) {
        try {
            //EventType = None時
            if (watchedEvent.getType() == Watcher.Event.EventType.None){
                if (watchedEvent.getState() == Watcher.Event.KeeperState.SyncConnected){
                    System.out.println("連接成功");
                    countDownLatch.countDown();
                }else if (watchedEvent.getState() == Watcher.Event.KeeperState.Disconnected){
                    System.out.println("斷開連接");
                }else if (watchedEvent.getState() == Watcher.Event.KeeperState.Expired){
                    System.out.println("會話超時");
                }else if (watchedEvent.getState() == Watcher.Event.KeeperState.AuthFailed){
                    System.out.println("認證失敗");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public String getUniqueID()  {
        String path ="";
        //創建臨時有序節點
        try {
            path = zooKeeper.create(defaultPath,new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return path.substring(8);
    }

    @Test
    public void test() throws Exception {
        ZKUniqueID zkUniqueID = new ZKUniqueID();
        for(int i=0 ;i<3;i++){
            System.out.println(zkUniqueID.getUniqueID());
        }
    }


}

  • curator實現

  • InterProcessMutex: 分佈式可重入排他鎖

  • InterProcessReadWriteLock:分佈式讀寫鎖


    @Test
    public void lock1() throws Exception {
        // 排他鎖
        // arg1:連接對象
        // arg2:節點路徑
        InterProcessLock interProcessLock = new InterProcessMutex(client, "/lock1");
        System.out.println("等待獲取鎖對象!");
        // 獲取鎖
        interProcessLock.acquire();
        for (int i = 1; i <= 10; i++) {
            Thread.sleep(3000);
            System.out.println(i);
        }
        // 釋放鎖
        interProcessLock.release();
        System.out.println("等待釋放鎖!");
    }

	//讀鎖
    @Test
    public void lock2() throws Exception {
        // 讀寫鎖
        InterProcessReadWriteLock interProcessReadWriteLock=new InterProcessReadWriteLock(client, "/lock1");
        // 獲取讀鎖對象
        InterProcessLock interProcessLock=interProcessReadWriteLock.readLock();
        System.out.println("等待獲取鎖對象!");
        // 獲取鎖
        interProcessLock.acquire();
        for (int i = 1; i <= 10; i++) {
            Thread.sleep(3000);
            System.out.println(i);
        }
        // 釋放鎖
        interProcessLock.release();
        System.out.println("等待釋放鎖!");
    }

	//寫鎖
    @Test
    public void lock3() throws Exception {
        // 讀寫鎖
        InterProcessReadWriteLock interProcessReadWriteLock=new InterProcessReadWriteLock(client, "/lock1");
        // 獲取寫鎖對象
        InterProcessLock interProcessLock=interProcessReadWriteLock.writeLock();
        System.out.println("等待獲取鎖對象!");
        // 獲取鎖
        interProcessLock.acquire();
        for (int i = 1; i <= 10; i++) {
            Thread.sleep(3000);
            System.out.println(i);
        }
        // 釋放鎖
        interProcessLock.release();
        System.out.println("等待釋放鎖!");
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章