package zooKeeper.zooKeeperLock;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
/**
DistributedLock lock = null;
try {
lock = new DistributedLock("127.0.0.1:2182","test");
lock.lock();
//do something...
} catch (Exception e) {
e.printStackTrace();
}
finally {
if(lock != null)
lock.unlock();
}
* @author xueliang
*
*/
public class DistributedLock implements Lock, Watcher{
private ZooKeeper zk;
private String root = "/build";//根
private String lockName;//竞争资源的标志
private String waitNode;//等待前一个锁
private String myZnode;//当前锁
private CountDownLatch latch;//计数器
private int sessionTimeout = 30000;
private List<Exception> exception = new ArrayList<Exception>();
/**
* 创建分布式锁,使用前请确认config配置的zookeeper服务可用
* @param config 127.0.0.1:2181
* @param lockName 竞争资源标志,lockName中不能包含单词lock
*/
public DistributedLock(String config, String lockName){
this.lockName = lockName;
// 创建一个与服务器的连接
try {
zk = new ZooKeeper(config, sessionTimeout, this);
Stat stat = zk.exists(root, false);
if(stat == null){
// 创建根节点
zk.create(root, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
}
} catch (IOException e) {
exception.add(e);
} catch (KeeperException e) {
exception.add(e);
} catch (InterruptedException e) {
exception.add(e);
}
}
/**
* zookeeper节点的监视器
*/
public void process(WatchedEvent event) {
if(this.latch != null) {
this.latch.countDown();
}
}
public void lock() {
if(exception.size() > 0){
throw new LockException(exception.get(0));
}
try {
if(this.tryLock()){
System.out.println("Thread " + Thread.currentThread().getId() + " " +myZnode + " get lock true");
return;
}
else{
waitForLock(waitNode, sessionTimeout);//等待锁
}
} catch (KeeperException e) {
throw new LockException(e);
} catch (InterruptedException e) {
throw new LockException(e);
}
}
public boolean tryLock() {
try {
String splitStr = "_lock_";
if(lockName.contains(splitStr))
throw new LockException("lockName can not contains \\u000B");
//创建临时子节点
myZnode = zk.create(root + "/" + lockName + splitStr, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(myZnode + " is created ");
//取出所有子节点
List<String> subNodes = zk.getChildren(root, false);
//取出所有lockName的锁
List<String> lockObjNodes = new ArrayList<String>();
for (String node : subNodes) {
String _node = node.split(splitStr)[0];
if(_node.equals(lockName)){
lockObjNodes.add(node);
}
}
Collections.sort(lockObjNodes);
System.out.println(myZnode + "==" + lockObjNodes.get(0));
if(myZnode.equals(root+"/"+lockObjNodes.get(0))){
//如果是最小的节点,则表示取得锁
return true;
}
//如果不是最小的节点,找到比自己小1的节点
String subMyZnode = myZnode.substring(myZnode.lastIndexOf("/") + 1);
waitNode = lockObjNodes.get(Collections.binarySearch(lockObjNodes, subMyZnode) - 1);
} catch (KeeperException e) {
throw new LockException(e);
} catch (InterruptedException e) {
throw new LockException(e);
}
return false;
}
public boolean tryLock(long time, TimeUnit unit) {
try {
if(this.tryLock()){
return true;
}
return waitForLock(waitNode,time);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private boolean waitForLock(String lower, long waitTime) throws InterruptedException, KeeperException {
Stat stat = zk.exists(root + "/" + lower,true);
//判断比自己小一个数的节点是否存在,如果不存在则无需等待锁,同时注册监听
if(stat != null){
System.out.println("Thread " + Thread.currentThread().getId() + " waiting for " + root + "/" + lower);
this.latch = new CountDownLatch(1);
this.latch.await(waitTime, TimeUnit.MILLISECONDS);
this.latch = null;
}
return true;
}
public void unlock() {
try {
System.out.println("unlock " + myZnode);
zk.delete(myZnode,-1);
myZnode = null;
zk.close();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
}
}
public void lockInterruptibly() throws InterruptedException {
this.lock();
}
public Condition newCondition() {
return null;
}
public class LockException extends RuntimeException {
private static final long serialVersionUID = 1L;
public LockException(String e){
super(e);
}
public LockException(Exception e){
super(e);
}
}
}
相关推荐
在这个例子中,`main`方法展示了如何连接到ZooKeeper服务器,创建一个持久化节点,读取其数据,然后删除该节点。`Watcher`接口用于处理ZNode的变更事件。 ZooKeeper的强一致性模型使得它在分布式环境中非常可靠。...
此外,ZooKeeper支持可插拔式身份验证,这意味着开发者可以选择适合自身安全需求的认证机制。 在一致性保证方面,ZooKeeper保证了一系列基本特性,例如顺序一致性、原子性以及单系统镜像。这些保证是构建可靠分布式...
在这个例子中,我们看到的是3.4.11版本的压缩包,通常以tar.gz格式提供,例如`zookeeper-3.4.11.tar.gz`。不过,提供的文件名是`zookeeper-3.4.11.tar_2`,这可能是下载过程中更改或错误的结果,应确保下载的是官方...
在一致性方面,ZooKeeper提供了强一致性保证,这保证了在分布式系统中数据的一致性是非常重要的。当系统中的某个节点发生故障时,ZooKeeper可以通过一系列的机制来确保系统的一致性和可靠性。 为了方便开发者使用,...
由于提到了Zookeeper,这个库可能还涉及到在分布式环境中管理这些备份,确保数据的安全性和一致性。在云原生环境下,这样的库可以帮助开发者构建能够跨多节点运行的服务,支持灵活的扩展和高可用性。为了更好地理解...
在这个例子中,"proxiesdotcom"可能是项目或库的名称,而"0.0.4"则代表了该库的版本号,".tar.gz"则是Linux和Unix系统中常见的归档和压缩格式,用于方便下载和分发。 从标签"zookeeper 分布式 云原生 cloud native...
在这个例子中,`riskiq-0.4.6`目录中应该包含`setup.py`,开发者可以通过运行`python setup.py install`来安装库。 `riskiq`库可能与Zookeeper有关,因为标签中提到了这个分布式协调服务。Zookeeper常用于管理...
这个方法在内部使用了CAS(Compare and Swap)算法,保证了在多个线程并发访问时,对变量的修改是安全的。 ```java import java.util.concurrent.atomic.AtomicInteger; public class VoteCounter { private ...
每个在PyPI上的项目都有一个唯一的名称,比如这个例子中的"always_updates"。用户可以通过pip(Python的包管理器)方便地从PyPI下载和安装这些库,例如使用命令`pip install always_updates`。然而,由于描述中提到...
总的来说,这个压缩包提供了对AWS Data Pipeline服务的类型增强支持,对于使用Python和AWS的开发者来说,它能帮助他们更好地管理数据工作流,同时通过myPy的静态类型检查提高代码的稳定性和可靠性。此外,结合分布式...
在这个例子中,没有列出具体的子文件,但通常会包含`setup.py`(用于安装库的Python脚本)、`README`(介绍库的用途和如何使用)、`LICENSE`(许可协议)、`requirements.txt`(依赖库列表)、源代码文件夹(如`src`...
在这个例子中,`google-cloud-containeranalysis`可能是项目的模块或服务名称,`2.6.0`代表了它的具体版本。 `google-cloud-containeranalysis`是一个Google提供的Python库,主要用于与Google的Container Analysis...
在分布式系统中,为了保证数据的一致性和安全性,分布式锁是一种常见的解决方案。本文将深入探讨如何使用Redisson和Curator框架来实现Java环境中的分布式锁。 首先,让我们来看一下Redisson实现的分布式锁。Redis是...
此外,还需要关注HBase的版本兼容性,例如在这个例子中,使用的是Hadoop-0.20.1-dev和Hbase-0.90.3。 在实际应用中,HBase适合于处理大规模、稀疏的多维数据,如日志数据、物联网设备数据等。通过它的列式存储、...
通过深入研究JLKEngine2013中间件平台开发包V7.6的源码例子,开发者不仅可以提升对AE+C#混合开发的理解,还能掌握中间件设计的通用原则和最佳实践。这将有助于在实际项目中构建更加高效、可扩展的系统架构,以应对日...
2. 接下来,你需要指定HDFS和ZooKeeper服务,因为这两个服务对于Solr的集群协调和数据存储至关重要。选择一个或多个机器来托管Solr服务器,这取决于你的集群规模和需求。 3. 点击“下一步”,配置Solr的相关参数,如...
这部分有助于理解如何在不安全的网络环境中保护数据安全。 9. **ch10.zip** - 可能包括网络性能监控和调试的相关代码,如日志记录、性能统计,或者异常检测和恢复机制。 10. **ch6.zip** - 可能涉及到网络编程中的...
4. **负载均衡**:当有多个服务提供者时,Dubbo会自动进行负载均衡,确保请求能均匀地分发到各个节点,提升系统整体性能。例如,它可以采用随机、轮询、最少活跃调用数等策略。 5. **容错机制**:在会员系统中,...