07.Curator计数器
1.SharedCount
- SharedCount - 管理一个共享的整数。所有看同样的路径客户端将有共享的整数(考虑ZK的正常一致性保证)的最高最新的值。
- SharedCountReader - 一个共享的整数接口,并允许监听改变它的值。
- SharedCountListener - 用于监听共享整数发生变化的监听器。
public class SharedCounterExample implements SharedCountListener
{
private static final int QTY = 5;
private static final String PATH = "/examples/counter";
public static void main(String[] args) throws IOException, Exception
{
final Random rand = new Random();
SharedCounterExample example = new SharedCounterExample();
CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 3));
client.start();
SharedCount baseCount = new SharedCount(client, PATH, 0);
baseCount.addListener(example);
baseCount.start();
List<SharedCount> examples = Lists.newArrayList();
ExecutorService service = Executors.newFixedThreadPool(QTY);
for (int i = 0; i < QTY; ++i)
{
final SharedCount count = new SharedCount(client, PATH, 0);
examples.add(count);
Callable<Void> task = new Callable<Void>()
{
@Override
public Void call() throws Exception
{
count.start();
Thread.sleep(rand.nextInt(10000));
count.setCount(rand.nextInt(10000));
System.out.println("计数器当前值:" + count.getVersionedValue().getValue());
System.out.println("计数器当前版本:" + count.getVersionedValue().getVersion());
System.out.println("trySetCount:" + count.trySetCount(count.getVersionedValue(), 123));
return null;
}
};
service.submit(task);
}
service.shutdown();
service.awaitTermination(10, TimeUnit.MINUTES);
for (int i = 0; i < QTY; ++i)
{
examples.get(i).close();
}
baseCount.close();
client.close();
System.out.println("OK!");
}
@Override
public void stateChanged(CuratorFramework client, ConnectionState newState)
{
System.out.println("连接状态: " + newState.toString());
}
@Override
public void countHasChanged(SharedCountReader sharedCount, int newCount) throws Exception
{
System.out.println("计数器值改变:" + newCount);
}
}
连接状态: CONNECTED
计数器当前值:1684
计数器当前版本:11
trySetCount:true
计数器值改变:123
计数器当前值:8425
计数器当前版本:13
trySetCount:true
计数器值改变:123
计数器当前值:9369
计数器当前版本:15
trySetCount:true
计数器值改变:123
计数器当前值:4075
计数器当前版本:17
trySetCount:true
计数器值改变:123
计数器当前值:9221
计数器当前版本:19
trySetCount:true
OK!

2.DistributedAtomicLong
public class DistributedAtomicLong implements DistributedAtomicNumber<Long>
{
private final DistributedAtomicValue value;
......
}
public class DistributedAtomicValue
{
......
AtomicValue<byte[]> trySet(MakeValue makeValue) throws Exception
{
MutableAtomicValue<byte[]> result = new MutableAtomicValue<byte[]>(null, null, false);
tryOptimistic(result, makeValue);
if ( !result.succeeded() && (mutex != null) )
{
tryWithMutex(result, makeValue);
}
return result;
}
......
}
- get(): 获取当前值
- increment(): 加一
- decrement(): 减一
- add(): 增加特定的值
- subtract(): 减去特定的值
- trySet(): 尝试设置计数值
- forceSet(): 强制设置计数值
public class DistributedAtomicLongExample
{
private static final int QTY = 5;
private static final String PATH = "/examples/counter";
public static void main(String[] args) throws IOException, Exception
{
final Random rand = new Random();
CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 3));
client.start();
List<DistributedAtomicLong> examples = Lists.newArrayList();
ExecutorService service = Executors.newFixedThreadPool(QTY);
for (int i = 0; i < QTY; ++i)
{
final DistributedAtomicLong count = new DistributedAtomicLong(client, PATH, new RetryNTimes(10, 10));
examples.add(count);
Callable<Void> task = new Callable<Void>()
{
@Override
public Void call() throws Exception
{
try
{
Thread.sleep(1000 + rand.nextInt(10000));
AtomicValue<Long> value = count.increment();
System.out.println("修改成功: " + value.succeeded());
if (value.succeeded())
{
System.out.println("修改之前的值:" + value.preValue() + " | 修改之后的值:" + value.postValue());
}
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
};
service.submit(task);
}
service.shutdown();
service.awaitTermination(10, TimeUnit.MINUTES);
client.close();
System.out.println("OK!");
}
}
修改成功: true
修改之前的值:0 | 修改之后的值:1
修改成功: true
修改之前的值:1 | 修改之后的值:2
修改成功: true
修改之前的值:2 | 修改之后的值:3
修改成功: true
修改之前的值:3 | 修改之后的值:4
修改成功: true
修改之前的值:4 | 修改之后的值:5
OK!

-------------------------------------------------------------------------------------------------------------------------------
07.Curator计数器的更多相关文章
- zookeeper之分布式锁以及分布式计数器(通过curator框架实现)
有人可能会问zookeeper我知道,但是curator是什么呢? 其实curator是apachede针对zookeeper开发的一个api框架是apache的顶级项目 他与zookeeper原生a ...
- PHP学习之[第07讲]PHP5.4 文件操作函数 之 图片计数器的实例
1.filetype():输出文件类型: 2.stat():获取文件的基本属性的数组: 3.clearstatcache().is_executable().isDir().idFile().scan ...
- Zookeeper开源客户端框架Curator简介
Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情 ...
- Zookeeper开源客户端框架Curator简介[转]
Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情 ...
- Python学习笔记——基础篇2【第三周】——计数器、有序字典、元组、单(双)向队列、深浅拷贝、函数、装饰器
目录 1.Python计数器Counter 2.Python有序字典OrderredDict 3.Python默认字典default 4.python可命名元组namedtuple 5.Python双 ...
- zookeeper(2)-curator
一.Curator介绍 zookeeper的提交人也说过,curator对于zookeeper而言就像是guava对于java差不多,更加优雅高效. 而且之前的zookeeper原生API,往往因为2 ...
- 15. 使用Apache Curator管理ZooKeeper
Apache ZooKeeper是为了帮助解决复杂问题的软件工具,它可以帮助用户从复杂的实现中解救出来. 然而,ZooKeeper只暴露了原语,这取决于用户如何使用这些原语来解决应用程序中的协调问题. ...
- Zookeeper客户端Curator基本API
在使用zookeper的时候一般不使用原生的API,Curator,解决了很多Zookeeper客户端非常底层的细节开发工作,包括连接重连.反复注册Watcher和NodeExistsExceptio ...
- MapReduce 计数器简介
转自:http://my.oschina.net/leejun2005/blog/276891?utm_source=tuicool&utm_medium=referral 1.计数器 简介 ...
随机推荐
- 【转】StackOverflow程序员推荐:每个程序员都应读的30本书
“如果能时光倒流,回到过去,作为一个开发人员,你可以告诉自己在职业生涯初期应该读一本,你会选择哪本书呢?我希望这个书单列表内容丰富,可以涵盖很多东西.” 很多程序员响应,他们在推荐时也写下自己的评语. ...
- python 脚本检测python 版本
通过sys 模块的sys_info可以返回当前python 的版本信息, 其返回值是一个元组, 比如(2, 6, 6, 'final', 0); 表示当前版本为2.6.6 , 我们可以利用这个变量的值 ...
- js实现密码强度
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- <OC>OC新特征array literals
类似于java5提供的autoboxing功能.以前的写法:NSNumber * number = [NSNumber numberWithInt:1];NSArray * array = [NSAr ...
- 转:windows 下 netsh 实现 端口映射(端口转发)
本文转自:本文出自 “httpyuntianjxxll.spac..” 博客,请务必保留此出处http://333234.blog.51cto.com/323234/1135361 -----hapr ...
- Unity3d + PureMVC框架搭建
0.流程:LoginView-SendNotification()---->LoginCommand--Execute()--->调用proxy中的函数操作模型数据--LoginProxy ...
- AOPR密码过滤器
在Advanced Office Password Recovery任一攻击的破解选项设置窗口都有一个“编辑密码过滤器”按钮,设置好AOPR密码破解工具的密码过滤器可以大大提高破解速度,下文将具体介绍 ...
- JavaScript匿名函数和回调函数
匿名函数的自调函数格式: (function(){ //代码 })(); <script type="text/javascript"> (function(){ al ...
- Java课后思考题
1.简述path和classpath的区别. path:path环境变量是系统环境变量中的一种,它用于保存一系列可执行文件的路径,每个路径之间以分号分隔.当在命令行窗口运行一个可执行文件时,操作系统首 ...
- POJ 3260 The Fewest Coins(多重背包问题, 找零问题, 二次DP)
Q: 既是多重背包, 还是找零问题, 怎么处理? A: 题意理解有误, 店主支付的硬币没有限制, 不占额度, 所以此题不比 1252 难多少 Description Farmer John has g ...