`
zoutm
  • 浏览: 95397 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

zookeeper系列之应用-分布式锁服务

阅读更多

前面zookeeper系统文章主要讲了zookeeper的实现原理,对我们使用好zookeeper有好处。如何使用zookeeper,让我开始实践之旅。通过简单的实现,zookeeper可以很容易提供分布式锁服务。

互斥锁的实现

在zookeeper的源代码包中recipe下有一个lock实现的例子,大家可以看到一个writelock的实现。writelock相当于一个互斥锁,但要和java提供的lock相比,用起来还是不太一样,需要我们进行一下包装,以下是对writeLock包装后的实现:

public class JoeZKLock implements GlobalLock{
	private static final Logger logger = Logger.getLogger(JoeZKLock.class);
	final static private String NO_PATH = "no_path";
	private WriteLock lock;
	final private String lockPath;
	final private ReentrantLock jvMLock = new ReentrantLock();

	public JoeZKLock(ZooKeeper zk, String lockPath) throws IOException {
		this.lockPath = lockPath;
		lock = new WriteLock(zk, lockPath, null);
	}

	public String lock() throws InterruptedException {
		jvMLock.lock();
		try {
			while (true) {
				if (lock.lock()) {
					return NO_PATH;
				}
			}
		} catch (Throwable e) {
			// here need catch Throwable, avoid throw
			// runtimeException
			// cause the jvmLock unrealsed
			logger.error("accquire global lock " + lockPath + " fail.", e);
			jvMLock.unlock();
			throw new InterruptedException();
		}
	}

	public void unlock(String path) {
		try {
			lock.unlock();
		} finally {
			//here ensure release the jvm lock
			jvMLock.unlock();
		}
	}
}
 

为什么需要在分布式锁的基础上再套一个jvmLock呢?主要原因是如果是同一个jvm的多个线程想要获取锁,如果在本地就互斥,就先在本地排队,这可以避免在zookeeper的锁节点产生大量的孩子,因为在锁实现的代码中需要getChildren,如果孩子越多,性能也越差。

 

读写锁的实现也大同小异。在此不在一一赘述。

在我们具体的lock server实现中提供了4种锁:

1.互斥锁

2.读写锁

3.path锁

4.id锁

通过这4种锁,完全能满足绝大多数锁的应用场景。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics