zookeeper实现分布式锁

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

zookeeper实现分布式锁

上一篇:linux修改文件权限


下一篇:android staticlayout文字绘制