Java并发包:CountDownLatch和CyclicBarrier

2024-01-21 16:50

本文主要是介绍Java并发包:CountDownLatch和CyclicBarrier,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章译自:http://tutorials.jenkov.com/java-util-concurrent/index.html
抽空翻译了一下这个教程的文章,后面会陆续放出,如有不妥,请批评指正。
转自请注明出处。

CountDownLatch

java.util.concurrent.CountDownLatch是一种并发结构,它允许一个或者多个线程等待一个给定的操作集合完成。

CountDownLatch初始化时需要给定一个总数。这个总数将会随着调用countDown()方法每次递减。通过调用await()方法,线程将会等到这个总数变为0。调用await()方法会阻塞线程直到那个总数递减到0为止。

下面是一个简单的例子。Decrementer在CountDownLatch上调用了countDown()3次之后,Waiter将会释放。

CountDownLatch latch = new CountDownLatch(3);Waiter      waiter      = new Waiter(latch);
Decrementer decrementer = new Decrementer(latch);new Thread(waiter).start();
new Thread(decrementer).start();Thread.sleep(4000);
public class Waiter implements Runnable{CountDownLatch latch = null;public Waiter(CountDownLatch latch) {this.latch = latch;}public void run() {try {latch.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Waiter Released");}
}
public class Decrementer implements Runnable {CountDownLatch latch = null;public Decrementer(CountDownLatch latch) {this.latch = latch;}public void run() {try {Thread.sleep(1000);this.latch.countDown();Thread.sleep(1000);this.latch.countDown();Thread.sleep(1000);this.latch.countDown();} catch (InterruptedException e) {e.printStackTrace();}}
}

添加一个客户端连接Zookeeper的例子。

/*** Created by charming on 2017/11/15.* 这里 CountDownLatch 用于停止(等待)主进程,直到客户端与ZooKeeper集合连接。* ZooKeeper集合通过监视器回调来回复连接状态。一旦客户端与ZooKeeper集合连接,监视器回调就会被调用,* 并且监视器回调函数调用CountDownLatch的countDown方法来释放锁,在主进程中await。*/
public class ZooKeeperConnection {// declare zookeeper instance to access ZooKeeper ensembleprivate ZooKeeper zoo;final CountDownLatch connectedSignal = new CountDownLatch(1);public ZooKeeper connect(String host) throws IOException,InterruptedException {zoo = new ZooKeeper(host, 5000, new Watcher() {public void process(WatchedEvent event) {if (event.getState() == Event.KeeperState.SyncConnected) {connectedSignal.countDown();}}});connectedSignal.await();return zoo;}// Method to disconnect from zookeeper serverpublic void close() throws InterruptedException {zoo.close();}
}

CyclicBarrier

java.util.concurrent.CyclicBarrier类的同步机制可以通过某些算法实现同步线程的执行,换句话说,它就像一个屏障(或着说栏栅),在任何线程执行之前,所有线程必须在此处等着,直到所有线程都到达才执行。下面是图解:
这里写图片描述
所有的线程会在CyclicBarrier上调用await()方法相互等待,一旦N个线程正在CyclicBarrier上等待,所有的线程都会释放并且继续执行。

创建 CyclicBarrier

当你创建一个CyclicBarrier,你需要指定在它上面有多少个体线程同时等待,下面是如何创建一个CyclicBarrier:

CyclicBarrier barrier = new CyclicBarrier(2);

有2个线程在CyclicBarrier上等待,这两个线程就会释放。

在CyclicBarrier上等待

下面是一个线程如何在CyclicBarrier上等待:

barrier.await();

你也可以指定线程等待的时间。当等待的时间过了,即使不是所有指定的线程都在CyclicBarrier上等待,线程也会被释放。下面是如何指定超时时间:

barrier.await(10, TimeUnit.SECONDS);

等待的线程会在CyclicBarrier上等待直至:

  • 最后的线程达到
  • 线程被另一个线程中断(另一个线程调用interrupt()方法)
  • 另一个等待的线程被中断
  • 另一个等待的线程等待超时
  • 某些外部线程调用了CyclicBarrier.reset()方法
CyclicBarrier Action

CyclicBarrire支持一种栏栅行为,一但最后的线程达到时线程将会执行。Runnable的栅栏行为通过CyclicBarrier的构造函数传递,像下面这样:

Runnable      barrierAction = ... ;
CyclicBarrier barrier       = new CyclicBarrier(2, barrierAction);
CyclicBarrier示例

下面的代码展示如何使用CyclicBarrier:

Runnable barrier1Action = new Runnable() {public void run() {System.out.println("BarrierAction 1 executed ");}
};
Runnable barrier2Action = new Runnable() {public void run() {System.out.println("BarrierAction 2 executed ");}
};CyclicBarrier barrier1 = new CyclicBarrier(2, barrier1Action);
CyclicBarrier barrier2 = new CyclicBarrier(2, barrier2Action);CyclicBarrierRunnable barrierRunnable1 =new CyclicBarrierRunnable(barrier1, barrier2);CyclicBarrierRunnable barrierRunnable2 =new CyclicBarrierRunnable(barrier1, barrier2);new Thread(barrierRunnable1).start();
new Thread(barrierRunnable2).start();

下面是CyclicBarrier类:

public class CyclicBarrierRunnable implements Runnable{CyclicBarrier barrier1 = null;CyclicBarrier barrier2 = null;public CyclicBarrierRunnable(CyclicBarrier barrier1,CyclicBarrier barrier2) {this.barrier1 = barrier1;this.barrier2 = barrier2;}public void run() {try {Thread.sleep(1000);System.out.println(Thread.currentThread().getName() +" waiting at barrier 1");this.barrier1.await();Thread.sleep(1000);System.out.println(Thread.currentThread().getName() +" waiting at barrier 2");this.barrier2.await();System.out.println(Thread.currentThread().getName() +" done!");} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}
}

下面是上面代码在控制台的输出结果,注意每次执行线程在控制台上打印的顺序也可能不一样。有时候可能是Thread-0先打印,有时候可能是Thread-1先打印。

Thread-0 waiting at barrier 1
Thread-1 waiting at barrier 1
BarrierAction 1 executed
Thread-1 waiting at barrier 2
Thread-0 waiting at barrier 2
BarrierAction 2 executed
Thread-0 done!
Thread-1 done!

这篇关于Java并发包:CountDownLatch和CyclicBarrier的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/630192

相关文章

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs

JAVA中安装多个JDK的方法

《JAVA中安装多个JDK的方法》文章介绍了在Windows系统上安装多个JDK版本的方法,包括下载、安装路径修改、环境变量配置(JAVA_HOME和Path),并说明如何通过调整JAVA_HOME在... 首先去oracle官网下载好两个版本不同的jdk(需要登录Oracle账号,没有可以免费注册)下载完

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

Java中Integer128陷阱

《Java中Integer128陷阱》本文主要介绍了Java中Integer与int的区别及装箱拆箱机制,重点指出-128至127范围内的Integer值会复用缓存对象,导致==比较结果为true,下... 目录一、Integer和int的联系1.1 Integer和int的区别1.2 Integer和in

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

JSONArray在Java中的应用操作实例

《JSONArray在Java中的应用操作实例》JSONArray是org.json库用于处理JSON数组的类,可将Java对象(Map/List)转换为JSON格式,提供增删改查等操作,适用于前后端... 目录1. jsONArray定义与功能1.1 JSONArray概念阐释1.1.1 什么是JSONA

Java JDK1.8 安装和环境配置教程详解

《JavaJDK1.8安装和环境配置教程详解》文章简要介绍了JDK1.8的安装流程,包括官网下载对应系统版本、安装时选择非系统盘路径、配置JAVA_HOME、CLASSPATH和Path环境变量,... 目录1.下载JDK2.安装JDK3.配置环境变量4.检验JDK官网下载地址:Java Downloads

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap