《賽博朋克2077》新概念圖 展示未曾出現的軍用飛行器
阿新 • • 發佈:2021-06-21
通過用zk建立臨時節點的特性,實現分散式鎖;
當前只有一個執行緒建立成功,然後close之後,該節點被刪除;
其他執行緒可以再次爭搶。
實現一個生成訂單號,幾個執行緒生成幾個訂單號,模仿多jvm對應多個執行緒
public class OrderNumCreateUtil {
private static int number = 0;
public String getOrderNumber(){
return "\t 生成訂單號:" + (++ number);
}
}
public interface ZkLock { public void zklock(); public void zkUnlock(); }
利用模板方法模式,把需要經常改的東西抽象出來,交給子類去實現
public abstract class ZkAbstractLock implements ZkLock{ public static final String ZKSERVER = "47.100.41.55:2181"; public static final int TIME_OUT = 45 * 1000; ZkClient zkClient = new ZkClient(ZKSERVER, TIME_OUT); protected String path = "/zklock0401"; protected CountDownLatch countDownLatch = null; @Override public void zklock() { if(tryZkLock()){ System.out.println(Thread.currentThread().getName() + "\t 佔用鎖成功。"); }else{ waitZkLock(); zklock(); } } public abstract void waitZkLock(); public abstract boolean tryZkLock(); @Override public void zkUnlock() { if(zkClient != null){ zkClient.close(); } System.out.println(Thread.currentThread().getName() + "\t 釋放鎖成功。"); System.out.println(); System.out.println(); } }
public class ZkDistributedLock extends ZkAbstractLock{ @Override public void waitZkLock() { //監聽path,1,資料是否改變或刪除 IZkDataListener iZkDataListener = new IZkDataListener() { @Override public void handleDataDeleted(String arg0) throws Exception { if(countDownLatch != null){ countDownLatch.countDown(); } } @Override public void handleDataChange(String arg0, Object arg1) throws Exception { } }; zkClient.subscribeDataChanges(path, iZkDataListener); if(zkClient.exists(path)){ //只能等著,因為鎖已經被其他執行緒佔領了 countDownLatch = new CountDownLatch(1); try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } } zkClient.unsubscribeDataChanges(path, iZkDataListener); } @Override public boolean tryZkLock() { try { //建立臨時節點 zkClient.createEphemeral(path); return true; } catch (Exception e) { return false; } } }
public class OrderService {
private OrderNumCreateUtil orderNumCreateUtil = new OrderNumCreateUtil();
private ZkLock zklock = new ZkDistributedLock();
public void getOrderNum(){
zklock.zklock();
try {
System.out.println("獲得編號:----->:" + orderNumCreateUtil.getOrderNumber());
} catch (Exception e) {
}finally{
zklock.zkUnlock();
}
}
}
public class Client {
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
new Thread(()->{
//模仿多jvm
new OrderService().getOrderNum();
},String.valueOf(i)).start();
}
}
}