curator之recipes之Barrier

参考文档: http://ifeve.com/zookeeper-barrier/
分布式系统中使用barrier阻塞多个进程,直到某个条件满足时,所有节点上的进行才会继续执行。
比如赛马比赛中, 等赛马陆续来到起跑线前。 一声令下,所有的赛马都飞奔而出。

栅栏Barrier

相关的类

  • DistributedBarrier

使用

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

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

setBarrier();

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

public void waitOnBarrier()

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

removeBarrier();

异常处理

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

代码示例

package 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 DistributeBarrierExample {
private static final int    QTY=5;
private static final String PATH="/examples/barrier";

public static void main(String[] args){
    TestingServer server=null;
    try {
        server=new TestingServer();
        CuratorFramework client=CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(100,3));
        client.start();

        ExecutorService pool=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<Void> task=new Callable<Void>(){
                @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;
                }
            };
             pool.submit(task);
        }
        Thread.sleep(10000);
        System.out.println("all Barrier instances should wait the condition");
        controlBarrier.removeBarrier();
        pool.shutdown();
        pool.awaitTermination(10, TimeUnit.MINUTES);

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
}

这个例子创建了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 until
all members have entered. When leave() is called, it blocks until all members have left.

Parameters:
client - the client
barrierPath - path to use
memberQty - the number of members in the barrier

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

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

代码示例

package 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.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<Void> task = new Callable<Void>() {
                        @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);

            }
        }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值