分布式Barrier是这样一个类: 它会阻塞所有节点上的等待进程,知道某一个被满足, 然后所有的节点继续进行。
    比如赛马比赛中, 等赛马陆续来到起跑线前。 一声令下,所有的赛马都飞奔而出。

1.栅栏Barrier

1.DistributedBarrier类说明
DistributedBarrier类实现了栅栏的功能。它的构造函数如下:
  1. /**
  2. * @param client client
  3. * @param barrierPath path to use as the barrier
  4. */
  5. public DistributedBarrier(CuratorFramework client, String barrierPath)
DistributedBarrier构造函数中barrierPath参数用来确定一个栅栏,只要barrierPath参数相同(路径相同)就是同一个栅栏。通常情况下栅栏的使用如下:
    1.主导client设置一个栅栏
    2.其他客户端就会调用waitOnBarrier()等待栅栏移除,程序处理线程阻塞
    3.主导client移除栅栏,其他客户端的处理程序就会同时继续运行。
DistributedBarrier类的主要方法如下:
  • setBarrier() - 设置栅栏
  • waitOnBarrier() - 等待栅栏移除
  • removeBarrier() - 移除栅栏
异常处理:DistributedBarrier会监控连接状态,当连接断掉时waitOnBarrier()方法会抛出异常。
2.编写示例程序
  1. public class DistributedBarrierExample
  2. {
  3. private static final int QTY = 5;
  4. private static final String PATH = "/examples/barrier";
  5. public static void main(String[] args) throws Exception
  6. {
  7. CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 3));
  8. client.start();
  9. ExecutorService service = Executors.newFixedThreadPool(QTY);
  10. DistributedBarrier controlBarrier = new DistributedBarrier(client, PATH);
  11. controlBarrier.setBarrier();
  12. for (int i = 0; i < QTY; ++i)
  13. {
  14. final DistributedBarrier barrier = new DistributedBarrier(client, PATH);
  15. final int index = i;
  16. Callable<Void> task = new Callable<Void>()
  17. {
  18. @Override
  19. public Void call() throws Exception
  20. {
  21. Thread.sleep((long) (3 * Math.random()));
  22. System.out.println("Client #" + index + " 等待");
  23. barrier.waitOnBarrier();
  24. System.out.println("Client #" + index + " 开始");
  25. return null;
  26. }
  27. };
  28. service.submit(task);
  29. }
  30. Thread.sleep(1000 * 3);
  31. System.out.println("所有的Client都在等待");
  32. controlBarrier.removeBarrier();
  33. service.shutdown();
  34. service.awaitTermination(10, TimeUnit.MINUTES);
  35. client.close();
  36. System.out.println("OK!");
  37. }
  38. }
这个例子创建了controlBarrier来设置栅栏和移除栅栏。我们创建了5个线程,在此Barrier上等待。最后移除栅栏后所有的线程才继续执行。
如果你开始不设置栅栏,所有的线程就不会阻塞住。
3.示例程序运行结果
    运行结果控制台:
  1. Client #1 等待
  2. Client #2 等待
  3. Client #0 等待
  4. Client #4 等待
  5. Client #3 等待
  6. 所有的Client都在等待
  7. Client #4 开始
  8. Client #2 开始
  9. Client #0 开始
  10. Client #3 开始
  11. Client #1 开始
  12. OK!
    运行时查看Zookeeper节点信息如下:

2.双栅栏Double Barrier

    双栅栏允许客户端在计算的开始和结束时同步。当足够的进程加入到双栅栏时,进程开始计算,当计算完成时,离开栅栏。双栅栏类是DistributedDoubleBarrier
1. DistributedDoubleBarrier类说明
DistributedDoubleBarrier类实现了双栅栏的功能。它的构造函数如下:
  1. // client - the client
  2. // barrierPath - path to use
  3. // memberQty - the number of members in the barrier
  4. public DistributedDoubleBarrier(CuratorFramework client, String barrierPath, int memberQty)
memberQty是成员数量,当enter方法被调用时,成员被阻塞,直到所有的成员都调用了enter。当leave方法被调用时,它也阻塞调用线程,知道所有的成员都调用了leave。
就像百米赛跑比赛, 发令枪响, 所有的运动员开始跑,等所有的运动员跑过终点线,比赛才结束。
注意:参数memberQty的值只是一个阈值,而不是一个限制值。当等待栅栏的数量大于或等于这个值栅栏就会打开!

与栅栏(DistributedBarrier)一样,双栅栏的barrierPath参数也是用来确定是否是同一个栅栏的,双栅栏的使用情况如下:
    1.从多个客户端在同一个路径上创建双栅栏(DistributedDoubleBarrier),然后调用enter()方法,等待栅栏数量达到memberQty时就可以进入栅栏。
    2.栅栏数量达到memberQty,多个客户端同时停止阻塞继续运行,直到执行leave()方法,等待memberQty个数量的栅栏同时阻塞到leave()方法中。
    3.memberQty个数量的栅栏同时阻塞到leave()方法中,多个客户端的leave()方法停止阻塞,继续运行。
DistributedDoubleBarrier类的主要方法如下:
  • enter()、enter(long maxWait, TimeUnit unit) - 等待同时进入栅栏
  • leave()、leave(long maxWait, TimeUnit unit) - 等待同时离开栅栏
异常处理:DistributedDoubleBarrier会监控连接状态,当连接断掉时enter()和leave方法会抛出异常。
2.编写示例程序
  1. public class DistributedBarrierDoubleExample
  2. {
  3. private static final int QTY = 5;
  4. private static final String PATH = "/examples/barrier";
  5. public static void main(String[] args) throws Exception
  6. {
  7. CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 3));
  8. client.start();
  9. ExecutorService service = Executors.newFixedThreadPool(QTY);
  10. for (int i = 0; i < (QTY + 2); ++i)
  11. {
  12. final DistributedDoubleBarrier barrier = new DistributedDoubleBarrier(client, PATH, QTY);
  13. final int index = i;
  14. Callable<Void> task = new Callable<Void>()
  15. {
  16. @Override
  17. public Void call() throws Exception
  18. {
  19. Thread.sleep((long) (3 * Math.random()));
  20. System.out.println("Client #" + index + " 等待");
  21. if(false == barrier.enter(5, TimeUnit.SECONDS))
  22. {
  23. System.out.println("Client #" + index + " 等待超时!");
  24. return null;
  25. }
  26. System.out.println("Client #" + index + " 进入");
  27. Thread.sleep((long) (3000 * Math.random()));
  28. barrier.leave();
  29. System.out.println("Client #" + index + " 结束");
  30. return null;
  31. }
  32. };
  33. service.submit(task);
  34. }
  35. service.shutdown();
  36. service.awaitTermination(10, TimeUnit.MINUTES);
  37. client.close();
  38. System.out.println("OK!");
  39. }
  40. }
注意:创建双栅栏的数量为:(QTY + 2),而创建双栅栏的参数为:new DistributedDoubleBarrier(client, PATH, QTY),当等待栅栏的数量大于或等于这个值(QTY)栅栏就会打开!
3.示例程序运行结果
    运行结果控制台:
  1. Client #0 等待
  2. Client #2 等待
  3. Client #3 等待
  4. Client #4 等待
  5. Client #1 等待
  6. Client #4 进入
  7. Client #2 进入
  8. Client #0 进入
  9. Client #1 进入
  10. Client #3 进入
  11. Client #4 结束
  12. Client #5 等待
  13. Client #2 结束
  14. Client #3 结束
  15. Client #6 等待
  16. Client #0 结束
  17. Client #1 结束
  18. Client #5 等待超时!
  19. Client #6 等待超时!
  20. OK!
    运行时查看Zookeeper节点信息如下:

-------------------------------------------------------------------------------------------------------------------------------

06.Curator Barrier的更多相关文章

  1. [译]ZOOKEEPER RECIPES-Barriers

    Barrier 在分布式系统中常使用Barrier来阻塞进程,当满足一定条件后再恢复进行后续操作.Barrier在Zookeeper中可以通过设计一个Barrier节点来实现.Barrier 节点存在 ...

  2. CuratorBarrier

    一.DistributedDoubleBarrier 同时开始,同时结束 package bjsxt.curator.barrier; import java.util.Random; import ...

  3. 六、curator recipes之屏障barrier

    简介 curator针对分布式场景实现了分布式屏障:barrier.我们在分布式系统中可以使用barrier去阻塞进程,知道某个条件被触发.其实跟Java多线程的barrier是一样的. 例如:当两个 ...

  4. Apache Curator获得真正的

    Apache Curator获得真正的 Curator它是Netflix一家公司来源Zookeeper顾客,与Zookeeper相比于提供本地客户端,Curator的抽象层次更高,简化了Zookeep ...

  5. Apache Curator入门实战

    Apache Curator入门实战 Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更高,简化了Zookeep ...

  6. Apache Curator: Zookeeper客户端

    Apache Curator Framework url: http://curator.apache.org/curator-framework/ The Curator Framework is ...

  7. Zookeeper开源客户端框架Curator简介

    Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情 ...

  8. 内存屏障(Memory barrier)-- 转发

    本文例子均在 Linux(g++)下验证通过,CPU 为 X86-64 处理器架构.所有罗列的 Linux 内核代码也均在(或只在)X86-64 下有效. 本文首先通过范例(以及内核代码)来解释 Me ...

  9. Zookeeper开源客户端框架Curator简介[转]

    Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理很多事情 ...

随机推荐

  1. 使用kubernetes创建容器一直处于ContainerCreating状态的原因查找与解决

    运行容器的时候,发现一直处于ContainerCreating状态,悲了个催,刚入手就遇到了点麻烦,下面来讲讲如何查找问题及解决的 运行容器命令: [root@master- ~]# kubectl ...

  2. Atitit. 解决80端口 System 占用pid 4,,找到拉个程序或者服务占用http 80服务

    Atitit. 解决80端口  System 占用pid 4,,找到拉个程序或者服务占用http服务 这个是http.sys系统服务占用了... net stop http ,三,没法儿终止 1. 寻 ...

  3. PHP.ini中配置屏蔽错误信息显示和保存错误日志

    在PHP程序运行过程中如果有错误发生,在浏览器上是否显示错误信息,以及显示错误信息的级别是我们在程序开发.调试.运营过程中需要控制的. root@(none):/alidata/www/default ...

  4. Nginx的Rewrite正则表达式,匹配非某单词

    Nginx的Rewrite正则表达式,匹配非某单词 由于要rewrite一个地址从 /mag/xx/xxx/ -> /m/xxx 但原先 /mag/xx/more/ 要保留 这就得写一个比较奇特 ...

  5. 从零开始,跟我一起做jblog项目(一)引言

    从零开始,跟我一起做jblog项目(一)引言 想做一个java版的blog,源自一个很久之前的想法 当时刚学习JAVA的web编程 想买自己的域名,自己的VPS,安装自己的WEB服务 用google ...

  6. spring-boot 中application.properties的各种配置

    ###########################################################datasource connect mysql################# ...

  7. lo4j 日志级别

    日志记录器(Logger)的行为是分等级的.如下表所示: 分为OFF.FATAL.ERROR.WARN.INFO.DEBUG.TRACE.ALL或者您定义的级别.Log4j建议只使用四个级别,优先级从 ...

  8. Unix系统编程()虚拟内存管理

    在之前学到过进程的内存布局中忽略了一个事实:这一布局存在于虚拟文件中. 因为对虚拟内存的理解将有助于后续对fork系统调用.共享内存和映射文件之类的主题阐述,这里还要学习一下有关虚拟内存的详细内容. ...

  9. API - 使用数据仓库 - 基础篇

    数据仓库是集成在Spider Studio中的一个重要功能, 利用它可以非常方便的保存采集到的数据, 然后导出或者在其他脚本中再利用. 数据仓库的全部功能都集成在DataManager这个静态类里面, ...

  10. REST学习

    RPC架构与REST架构 RPC:RPC将服务器看作一些列动作的集合(需要做某件事) REST:将服务器看作分布式对象集合,客户端通过调用这些对象上的方法来执行特定的任务,组件交互的可伸缩性.接口的通 ...