博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
跟着实例学习ZooKeeper的用法: Barrier
阅读量:6246 次
发布时间:2019-06-22

本文共 5515 字,大约阅读时间需要 18 分钟。

分布式Barrier是这样一个类: 它会阻塞所有节点上的等待进程,知道某一个被满足, 然后所有的节点继续进行。

比如赛马比赛中, 等赛马陆续来到起跑线前。 一声令下,所有的赛马都飞奔而出。

栅栏Barrier

DistributedBarrier类实现了栅栏的功能。 它的构造函数如下:

public DistributedBarrier(CuratorFramework client, String barrierPath)Parameters:client - clientbarrierPath - path to use as the barrier

首先你需要设置栅栏,它将阻塞在它上面等待的线程:

setBarrier();

然后需要阻塞的线程调用“方法等待放行条件:

public void waitOnBarrier()

当条件满足时,移除栅栏,所有等待的线程将继续执行:

removeBarrier();

异常处理 DistributedBarrier 会监控连接状态,当连接断掉时waitOnBarrier()方法会抛出异常。

看一个例子:

package com.colobu.zkrecipe.barrier;import java.util.concurrent.Callable;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;import org.apache.curator.framework.CuratorFramework;import org.apache.curator.framework.CuratorFrameworkFactory;import org.apache.curator.framework.recipes.barriers.DistributedBarrier;import org.apache.curator.retry.ExponentialBackoffRetry;import org.apache.curator.test.TestingServer;public class DistributedBarrierExample {    private static final int QTY = 5;    private static final String PATH = "/examples/barrier";    public static void main(String[] args) throws Exception {        try (TestingServer server = new TestingServer()) {            CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(1000, 3));            client.start();            ExecutorService service = Executors.newFixedThreadPool(QTY);            DistributedBarrier controlBarrier = new DistributedBarrier(client, PATH);            controlBarrier.setBarrier();            for (int i = 0; i < QTY; ++i) {                final DistributedBarrier barrier = new DistributedBarrier(client, PATH);                final int index = i;                Callable
task = new Callable
() { @Override public Void call() throws Exception { Thread.sleep((long) (3 * Math.random())); System.out.println("Client #" + index + " waits on Barrier"); barrier.waitOnBarrier(); System.out.println("Client #" + index + " begins"); return null; } }; service.submit(task); } Thread.sleep(10000); System.out.println("all Barrier instances should wait the condition"); controlBarrier.removeBarrier(); service.shutdown(); service.awaitTermination(10, TimeUnit.MINUTES); } }}

这个例子创建了controlBarrier来设置栅栏和移除栅栏。 我们创建了5个线程,在此Barrier上等待。 最后移除栅栏后所有的线程才继续执行。

如果你开始不设置栅栏,所有的线程就不会阻塞住。

双栅栏Double Barrier

双栅栏允许客户端在计算的开始和结束时同步。当足够的进程加入到双栅栏时,进程开始计算, 当计算完成时,离开栅栏。 双栅栏类是DistributedDoubleBarrier。 构造函数为:

public DistributedDoubleBarrier(CuratorFramework client,                                String barrierPath,                                int memberQty)Creates the barrier abstraction. memberQty is the number of members in the barrier. When enter() is called, it blocks untilall members have entered. When leave() is called, it blocks until all members have left.Parameters:client - the clientbarrierPath - path to usememberQty - the number of members in the barrier

memberQty是成员数量,当enter方法被调用时,成员被阻塞,直到所有的成员都调用了enter。 当leave方法被调用时,它也阻塞调用线程, 知道所有的成员都调用了leave。 就像百米赛跑比赛, 发令枪响, 所有的运动员开始跑,等所有的运动员跑过终点线,比赛才结束。

DistributedBarrier 会监控连接状态,当连接断掉时enter()leave方法会抛出异常。

例子代码:

package com.colobu.zkrecipe.barrier;import java.util.concurrent.Callable;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;import org.apache.curator.framework.CuratorFramework;import org.apache.curator.framework.CuratorFrameworkFactory;import org.apache.curator.framework.recipes.barriers.DistributedBarrier;import org.apache.curator.framework.recipes.barriers.DistributedDoubleBarrier;import org.apache.curator.retry.ExponentialBackoffRetry;import org.apache.curator.test.TestingServer;public class DistributedBarrierExample {    private static final int QTY = 5;    private static final String PATH = "/examples/barrier";    public static void main(String[] args) throws Exception {        try (TestingServer server = new TestingServer()) {            CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(1000, 3));            client.start();            ExecutorService service = Executors.newFixedThreadPool(QTY);            for (int i = 0; i < QTY; ++i) {                final DistributedDoubleBarrier barrier = new DistributedDoubleBarrier(client, PATH, QTY);                final int index = i;                Callable
task = new Callable
() { @Override public Void call() throws Exception { Thread.sleep((long) (3 * Math.random())); System.out.println("Client #" + index + " enters"); barrier.enter(); System.out.println("Client #" + index + " begins"); Thread.sleep((long) (3000 * Math.random())); barrier.leave(); System.out.println("Client #" + index + " left"); return null; } }; service.submit(task); } service.shutdown(); service.awaitTermination(10, TimeUnit.MINUTES); } }}
  • 转载自 
你可能感兴趣的文章
Shell脚本语法
查看>>
scrapy与xpath的坑
查看>>
windows 下安装tidylib
查看>>
MapReduce的那些事
查看>>
CentOS6.5环境下OpenSSL实战:自己搭建CA中心,申请,签发,吊销,导入证书,SSL 握手详解...
查看>>
关于:url伪静态
查看>>
Android开发之制作圆形头像自定义View,直接引用工具类,加快开发速度。带有源代码学习...
查看>>
申请微信公众号
查看>>
python中 __name__的使用
查看>>
(译)iPhone: 用公开API创建带小数点的数字键盘 (OS 3.0, OS 4.0)
查看>>
WSUS客户端升级使用命令行快速自动更新系统补丁包
查看>>
如何不让上网影响工作?看看作家怎么做
查看>>
MySQL 获得当前日期时间(以及时间的转换)
查看>>
solrcloud分布式集群部署及索引操作实例
查看>>
PHP URL 重定向 的三种方法(转)
查看>>
ubuntu14.04安装docker
查看>>
Android ADT 离线下载技巧(告别在线安装的麻烦)
查看>>
MySQL umask 导致备份报错
查看>>
LunarPages LPCP面板设置访问Web Mail教程
查看>>
java Atomic
查看>>