Curator典型使用场景之分布式Barrier。
来源:互联网 发布:淘宝黑搜20单五天必爆 编辑:程序博客网 时间:2024/06/07 04:06
Barrier是一种用来控制多线程之间同步的经典方式,在JDK中也自带了CyclicBarrier实现。下面通过模拟一个赛跑比赛来演示CyclicBarrier的用法。
使用CyclicBarrier模拟一个赛跑比赛
public class Recipes_CyclicBarrier {
public static CyclicBarrier barrier = new CyclicBarrier(3);
public static void main(String[] args) throws IOException, InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new Thread(new Runner("1号选手")));
executor.submit(new Thread(new Runner("2号选手")));
executor.submit(new Thread(new Runner("3号选手")));
executor.shutdown();
}
}
class Runner implements Runnable {
private String name;
public Runner(String name) {
this.name = name;
}
public void run() {
System.out.println(name + "准备好了.");
try {
Recipes_CyclicBarrier.barrier.await();
} catch (Exception e) {}
System.out.println(name + " 起跑!");
}
}
上面就是一个使用JDK自带的CyclicBarrier实现的赛跑比赛程序,可以看到多线程在并发情况下,都会准确的等待所有县城都处于就绪状态后才开始同时执行其他业务逻辑。如果是在同一个JVM中的话,使用CyclicBarrier完全可以解决诸如此类的多线程同步问题。但是,如果在分布式环境中又该如何解决呢?Curator中提供DistributedBarrier就是用来实现分布式Barrier的。
使用Curator实现分布式Barrier
// 使用Curator实现分布式Barrier
public class Recipes_Barrier {
static String barrier_path = "/curator_recipes_barrier_path";
static DistributedBarrier barrier;
public static void main(String[] args) throws Exception {
for(int i = 0; i <5; i ++) {
new Thread(new Runnable() {
public void run() {
try {
CuratorFramework client = CuratorFrameworkFactory.builder().connectString("domain1.book.zookeeper:2181").retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
client.start();
barrier = new DistributedBarrier(client, barrier_path);
System.out.println(Thread.currentThread().getName() + "号barrier设置");
barrier.setBarrier();
barrier.waitOnBarrier();
System.err.println("启动...");
} catch (Exception e) {}
}
}).start();
Thread.sleep(2000);
barrier.removeBarrier();
}
}
}
运行程序,输出结果如下:
在上面这个实例程序中,我们模拟了5个线程,通过调用DistributedBarrier.setBarrier()方法来完成Barrier的设置,并通过调用DistributedBarrier.waitOnBarrier()方法来等待Barrier的释放。然后在主线程中,通过调用DistributedBarrier.removeBarrier()方法来释放Barrier,同时触发所有等待该Barrier的5个线程同时进行各自的逻辑。
和上面这种由主线程来触发Barrier释放不同的是,Curator还提供了另一种线程自发触发Barrier释放的模式,使用方法见下面示例。
使用Curator实现另一种线程自发触发Barrier释放的模式
public class Recipes_Barrier2 {
static String barrier_path = "/curator_recipes_barrier_path";
public static void main(String[] args) throws Exception {
for(int i = 0; i <5; i ++) {
new Thread(new Runnable() {
public void run() {
try {
CuratorFramework client = CuratorFrameworkFactory.builder().connectString("domain1.book.zookeeper:2181").retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();
client.start();
DistributedBarrier barrier= new DistributedBarrier(client, barrier_path, 5);
Thread.sleep(Math.round(Math.random() * 3000));
System.out.println(Thread.currentThread().getName() + "号barrier设置");
barrier.enter();
System.out.println("启动...");
Thread.sleep(Math.round(Math.random() * 3000));
barrier.leave();
System.out.println("退出...");
} catch (Exception e) {}
}
}).start();
Thread.sleep(2000);
barrier.removeBarrier();
}
}
}
运行程序,输出结果如下。 上面这个示例程序就是一个和JDK自带的CyclicBarrier非常类似的实现了,他们都指定了进入Barrier的成员数阈值,例如上面示例程序中的“5”.每个Barrier的参与者都会在调用DistributedDoubleBarrier.enter()方法之后进行等待,此时处于准备进入状态。一旦准备进入Barrier的成员数达到5个后,所有的成员会被同时触发进入。之后调用DistributedDoubleBarrier.leave()方法则会再次等待,此时处于退出状态。一旦准备退出Barrier的成员数达到5个后,所有的成员同样会被同时触发退出。因此,使用Curator的DistributedDoubleBarrier能够很好的实现一个分布式Barrier,并控制其同时进入和退出。
- Curator典型使用场景之分布式Barrier。
- Curator典型使用场景之分布式锁。
- Curator典型使用场景之分布式计数器。
- Curator典型使用场景之事件监听。
- Curator典型使用场景之Master选举。
- curator之recipes之Barrier
- Zookeeper实例Curator API-分布式Barrier
- 分布式消息队列RabbitMQ之三:四种典型使用场景和代码示例
- ZooKeeper的典型应用场景之分布式协调/通知。
- ZooKeeper的典型应用场景之分布式锁。
- ZooKeeper的典型应用场景之分布式队列。
- zookeeper典型使用场景
- ZooKeeper典型使用场景
- Curator分布式锁之生成流水号
- Zookeeper框架Curator之分布式锁-yellowcong
- Zookeeper框架Curator之分布式计数器-yellowcong
- Zookeeper框架Curator之分布式DistributedBarrier -yellowcong
- ZooKeeper典型使用场景一览
- 揭秘阿里小蜜:基于检索模型和生成模型相结合的聊天引擎 | PaperDaily #25
- 谈谈单元测试之(四):测试工具 TestNG
- 翻译内核uvcvideo.txt
- vue 路由简单实例
- 数据库数据操作
- Curator典型使用场景之分布式Barrier。
- Tensorflow的反卷积(上采样)
- org.xml.sax.SAXParseException; 元素内容必须由格式正确的字符数据或标记组成
- Java数据类型转换
- WebSocket简介和例子
- decaf/internal/net/ssl/openssl/OpenSSLSocket.cpp:667:50: error: invalid use of incomplete type ‘X509
- 算法导论详解(1) 第二章算法基础+python实现
- AI-Tensorflow—windows64bit下pip install scikit-image安装错误
- xml文件的编写/解析和元素定义