zookeeper curator 可重入與不可重入分散式鎖
阿新 • • 發佈:2019-01-04
轉載自https://www.cnblogs.com/zhangjunqing/p/7823626.html
基礎知識:http://www.cnblogs.com/LiZhiW/p/4931577.html
專案路徑:https://gitee.com/zhangjunqing/spring-boot
1 可重入讀寫鎖示例程式碼如下(lock.acquire加幾個,就必須使用幾個lock.release()釋放):
package com.topsec.lock; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.recipes.locks.InterProcessMutex; import org.apache.curator.retry.ExponentialBackoffRetry; /** * 測試可重入鎖(可以多次獲得鎖不會被阻塞,釋放時也需釋放多把鎖) * @author 76524 * */ public class SharedReentrantLock1 implements Runnable{ private InterProcessMutex lock;//可重入鎖實現類 private String lockPAth = "/lock/shareLock"; private int i; private String clientName; //zookeeper叢集地址 public static final String ZOOKEEPERSTRING = "192.168.99.129:2181,192.168.99.153:2181,192.168.99.171:2181"; public SharedReentrantLock1(CuratorFramework client,String clientName) { lock = new InterProcessMutex(client, lockPAth); this.clientName = clientName; } public void run() { try { Thread.sleep((new java.util.Random().nextInt(2000))); lock.acquire(); //增加第一把鎖 if(lock.isAcquiredInThisProcess()) { System.out.println(clientName + " 獲得鎖"); i++; } lock.acquire(); //增加第二把鎖 } catch (Exception e) { e.printStackTrace(); }finally { try { System.out.println(clientName+"釋放第一把鎖"); lock.release(); System.out.println(clientName+"釋放第二把鎖"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { CuratorFramework client = CuratorFrameworkFactory.newClient(ZOOKEEPERSTRING, new ExponentialBackoffRetry(1000, 3)); client.start(); //啟動100個執行緒進行測試 for(int i = 0;i<100;i++) { SharedReentrantLock1 sharedReentrantLock = new SharedReentrantLock1(client, "第"+i+"個客戶端:"); Thread thread = new Thread(sharedReentrantLock); thread.start(); } } }
2:不可重入鎖示例程式碼如下(lock.acquire加幾個都只相當於加一個):
package com.topsec.lock; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.recipes.locks.InterProcessSemaphoreMutex; import org.apache.curator.retry.ExponentialBackoffRetry; /** * 測試不可重入鎖(只能獲得一次鎖,使用完後釋放) * @author 76524 * */ public class SharedNOReentrantLock implements Runnable{ private InterProcessSemaphoreMutex lock;//不可重入鎖 private String lockPAth = "/lock/shareLock"; private int i; private String clientName; //zookeeper叢集地址 public static final String ZOOKEEPERSTRING = "192.168.99.129:2181,192.168.99.153:2181,192.168.99.171:2181"; public SharedNOReentrantLock(CuratorFramework client,String clientName) { lock = new InterProcessSemaphoreMutex(client, lockPAth); this.clientName = clientName; } public void run() { try { Thread.sleep((new java.util.Random().nextInt(2000))); lock.acquire(); //增加第一把鎖 if(lock.isAcquiredInThisProcess()) { System.out.println(clientName + " 獲得鎖"); i++; } lock.acquire(); //增加第二把鎖這個鎖相當於不起作用 } catch (Exception e) { e.printStackTrace(); }finally { try { // lock.release(); System.out.println(clientName+"釋放第一把鎖"); lock.release(); System.out.println(clientName+"釋放第二把鎖"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { CuratorFramework client = CuratorFrameworkFactory.newClient(ZOOKEEPERSTRING, new ExponentialBackoffRetry(1000, 3)); client.start(); for(int i = 0;i<100;i++) { SharedReentrantLock2 sharedReentrantLock = new SharedReentrantLock2(client, "第"+i+"個客戶端:"); Thread thread = new Thread(sharedReentrantLock); thread.start(); } } }
ps:最後的基於訊號量的不可重入鎖,看其構造方法其實maxLeases的值設定為1,這樣每次只能有一個獲取到鎖,其他等待其釋放lease後才能獲取到鎖。