1. 程式人生 > 遊戲 >《賽博朋克2077》新概念圖 展示未曾出現的軍用飛行器

《賽博朋克2077》新概念圖 展示未曾出現的軍用飛行器

通過用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();
		}
	}
}