Zookeeper实现独占锁

排它锁(Exclusive Locks,简称X锁),又称为写锁。

如果事务T1对数据对象o1加上了排它锁,那么在整个加锁期间,只允许事务T1对o1进行读取和更新操作,其他任何事务都不能在这个数据对象进行任何类型的操作(不能再对该对象加锁),直至T1释放了排他锁。

public class DistributeLock implements Watcher{
	private ZooKeeper zooKeeper;
	/** zookeeper服务器地址 */
	public static final String connectString = "192.168.50.110:2181,192.168.50.111:2181,192.168.50.112:2181";
	/** 定义session失效时间 */
	public static final int sessionTimeout = 5000;
	private String path = "/lock";
	
	private CountDownLatch cl;
	private CountDownLatch cl2 = new CountDownLatch(1);
	
	Thread t;
	public DistributeLock(String host ,final String path) {
		try {
			this.zooKeeper = new ZooKeeper(host, 6000,this);
			
			try {
				cl2.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		this.path = path;
	}
	
	/**
	 * 加锁
	 */
	public void lock() {
		try {
			zooKeeper.create(path, path.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
		 } catch (Exception e) {
			 try {
				cl= new CountDownLatch(1);
				cl.await(1000,TimeUnit.MICROSECONDS);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
		    lock();
		}
	}
	/**
	 * 释放锁
	 */
	public  void unlock() {
		try {
			zooKeeper.exists(path, true);
			zooKeeper.delete(path, -1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (KeeperException e) {
			e.printStackTrace();
		}
		
	}

	@Override
	public void process(WatchedEvent event) {
		
		System.out.println("进入 process 。。。。。event = " + event);
		
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		if (event == null) {
			return;
		}
		
		// 连接状态
		KeeperState keeperState = event.getState();
		// 事件类型
		EventType eventType = event.getType();
		// 受影响的path
		String path = event.getPath();
		
		String logPrefix="";
		System.out.println(logPrefix + "收到Watcher通知");
		System.out.println(logPrefix + "连接状态:\t" + keeperState.toString());
		System.out.println(logPrefix + "事件类型:\t" + eventType.toString());

		if (KeeperState.SyncConnected == keeperState) {
			// 成功连接上ZK服务器
			if (EventType.None == eventType) {
				System.out.println( "成功连接上ZK服务器");
				cl2.countDown();
			} 
			//删除节点
			else if (EventType.NodeDeleted == eventType) {
				System.out.println("线程:"+t.getName()+logPrefix + "节点 " + path + " 被删除");
			}
			else ;
		} 
		else if (KeeperState.Disconnected == keeperState) {
			System.out.println(logPrefix + "与ZK服务器断开连接");
		} 
		else if (KeeperState.AuthFailed == keeperState) {
			System.out.println(logPrefix + "权限检查失败");
		} 
		else if (KeeperState.Expired == keeperState) {
			System.out.println(logPrefix + "会话失效");
		}
		else ;

		System.out.println("--------------------------------------------");

	}
}

测试类(不加锁):

public class LockTest implements Runnable {
	static int i = 0;

	DistributeLock lock = new DistributeLock(ZookeeperUtil.connectString, "/lock");

	@Override
	public void run() {
		// lock.lock();
		for (int j = 0; j < 1000000; j++) {
			i++;
		}
		// lock.unlock();
	}

	public static void main(String[] args) throws InterruptedException {
		LockTest lockTest2 = new LockTest();
		LockTest lockTest1 = new LockTest();
		Thread thread = new Thread(lockTest2);
		Thread thread2 = new Thread(lockTest1);
		thread.start();
		thread2.start();
		thread.join();
		thread2.join();
		System.out.println(i);

	}

测试结果:

测试类(加锁):

public class LockTest implements Runnable {
	static int i = 0;

	DistributeLock lock = new DistributeLock(ZookeeperUtil.connectString, "/lock");

	@Override
	public void run() {
		lock.lock();
		for (int j = 0; j < 1000000; j++) {
			i++;
		}
		lock.unlock();
	}

	public static void main(String[] args) throws InterruptedException {
		LockTest lockTest2 = new LockTest();
		LockTest lockTest1 = new LockTest();
		Thread thread = new Thread(lockTest2);
		Thread thread2 = new Thread(lockTest1);
		thread.start();
		thread2.start();
		thread.join();
		thread2.join();
		System.out.println(i);

	}

}

测试结果:


阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页