2 原生Zookeeper 实现分布式锁
生活随笔
收集整理的這篇文章主要介紹了
2 原生Zookeeper 实现分布式锁
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1 原生分布式鎖
package com.ccb.zookeeper.lock;import org.apache.zookeeper.*; import org.apache.zookeeper.data.Stat;import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.concurrent.CountDownLatch;public class DistributedLock {private final String connectString = "172.16.171.2:2181,172.16.171.3:2181,172.16.171.4:2181";private final int sessionTimeout = 2000;ZooKeeper zooKeeper = null;private CountDownLatch countDownLatch = new CountDownLatch(1);private CountDownLatch waitLatch = new CountDownLatch(1);private String waitPath;String currentMode ;public DistributedLock() throws InterruptedException, KeeperException, IOException {//獲取連接zooKeeper = new ZooKeeper(connectString, sessionTimeout, new Watcher() {@Overridepublic void process(WatchedEvent watchedEvent) {//countDownLatch 如果連接上zk,可以釋放if (watchedEvent.getState() == Event.KeeperState.SyncConnected){countDownLatch.countDown();}//waitLatch 需要釋放if (watchedEvent.getType() == Event.EventType.NodeDeleted && watchedEvent.getPath().equals(waitPath)){waitLatch.countDown();}}});//等待zk正常連接后,往下走程序countDownLatch.await();//判斷根節點/locks是否存在Stat stat = zooKeeper.exists("/locks", false);if (stat == null){//創建一下根節點zooKeeper.create("/locks","locks".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);}}//對zk加鎖public void zkLock() throws InterruptedException, KeeperException {//創建對應的臨時帶序號節點currentMode = zooKeeper.create("/locks/" + "seq-", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);//判斷創建的節點是否是最小的序號節點,如果是獲取到鎖,如果不是,監聽他序號前一個節點List<String> children = zooKeeper.getChildren("/locks", false);//如果children只有一個值,那就直接獲取鎖,如果有多個節點,需要判斷誰最小if (children.size() == 1){return;} else {Collections.sort(children);//獲取節點的名稱 seq-00000000String thisNode = currentMode.substring("/locks/".length());//通過seq-00000000獲取該節點在children集合的位置int index = children.indexOf(thisNode);if (index == -1){System.out.println("數據異常");}else if (index == 0){//就一個節點,可以獲取鎖了return;}else {//需要監聽 他前一個節點變化waitPath = "/locks/"+ children.get(index - 1 );zooKeeper.getData(waitPath,true,null);//等待監聽waitLatch.await();return;}}}//解鎖public void unZkLock() throws InterruptedException, KeeperException {//刪除節點zooKeeper.delete(currentMode,-1);} }2 測試分布式鎖
package com.ccb.zookeeper.lock;import org.apache.zookeeper.KeeperException;import java.io.IOException;public class DistributedLockTest {public static void main(String[] args) throws IOException, InterruptedException, KeeperException {final DistributedLock lock1 = new DistributedLock();final DistributedLock lock2 = new DistributedLock();new Thread(new Runnable() {@Overridepublic void run() {try {lock1.zkLock();System.out.println("線程1 啟動,獲取到鎖");Thread.sleep(5 * 1000);lock1.unZkLock();System.out.println("線程1 釋放鎖");} catch (InterruptedException e) {e.printStackTrace();} catch (KeeperException e) {e.printStackTrace();}}}).start();new Thread(new Runnable() {@Overridepublic void run() {try {lock2.zkLock();System.out.println("線程2 啟動,獲取到鎖");Thread.sleep(5 * 1000);lock2.unZkLock();System.out.println("線程2 釋放鎖");} catch (InterruptedException e) {e.printStackTrace();} catch (KeeperException e) {e.printStackTrace();}}}).start();} }3 Test結果
線程1 啟動,獲取到鎖 線程1 釋放鎖 線程2 啟動,獲取到鎖 線程2 釋放鎖 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的2 原生Zookeeper 实现分布式锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1 Zookeeper安装
- 下一篇: 3 Curator框架实现分布式锁