Java中的 CyclicBarrier详解

Java中的 CyclicBarrier详解

1. 什么是CyclicBarrier

CyclicBarrier是Java并发包中的一个类,可以让一组线程在某个条件达成时全部同时开始执行。简而言之,CyclicBarrier是一种同步机制,它允许指定的线程等待彼此到达某个同步点。

CyclicBarrier和CountDownLatch都可以用于线程间的同步,但它们之间也存在一些区别。CountDownLatch是一种能够使一个或多个线程等待一系列指定的任务执行完后再执行的同步机制,而CyclicBarrier是一种等待所有线程都满足某个条件后再继续执行的同步机制。

CyclicBarrier的用法非常简单,只需要在创建实例时指定同步点即可,线程在运行过程中到达同步点时将被阻塞,直到所有线程都到达同步点后才会一起继续执行。

2. CyclicBarrier常用方法

CyclicBarrier类提供了一些方法可以用于实现线程间的同步控制。

2.1 构造方法

CyclicBarrier的构造方法有两种基本形式:

public CyclicBarrier(int parties)

构造一个新的CyclicBarrier,它将在指定数量的线程(称为parties)等待之后启动执行。

public CyclicBarrier(int parties, Runnable barrierAction)

构造一个新的CyclicBarrier,它将在指定数量的线程等待之后启动执行,并会执行指定的Runnable。

2.2 await()

CyclicBarrier的唯一方法是await(),调用await()表示该线程已经到达了同步点。当某个线程调用await()时,它将会被阻塞,而其他线程继续执行,直到所有线程都到达了同步点。

public void await() throws InterruptedException, BrokenBarrierException;

2.3 reset()

CyclicBarrier还提供了reset()方法,用于重置同步点。在调用reset()方法后,所有已经在等待的线程都将抛出BrokenBarrierException异常。

public void reset();

3. CyclicBarrier的使用示例

下面的示例演示了如何使用CyclicBarrier来实现一批线程同时开始执行:


import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " is working");
            }
        });

        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " is waiting");
                    try {
                        cyclicBarrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " is working");
                }
            }, "Thread-" + i).start();
        }
    }
}

运行结果如下:

Thread-2 is waiting
Thread-3 is waiting
Thread-4 is waiting
Thread-0 is waiting
Thread-1 is waiting
Thread-2 is working
Thread-3 is working
Thread-4 is working
Thread-0 is working
Thread-1 is working

上面的代码中,我们创建了一个CyclicBarrier实例,其参数parties为5,表示要等待5个任务完成。在每一个线程中,我们先打印出当前线程正在等待,然后调用cyclicBarrier.await()方法将线程阻塞。当所有线程都到达了同步点后,会执行CyclicBarrier的构造方法中指定的Runnable,同时所有被阻塞的线程开始同步执行,打印出"Thread-x is working",x为线程的编号。

另一个示例演示了如何使用CyclicBarrier来模拟比赛的开始、进行和结束,其中比赛有三个阶段:准备、开始、结束。


import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class RaceDemo {
    private static CyclicBarrier cyclicBarrier;

    public static void main(String[] args) throws InterruptedException {
        cyclicBarrier = new CyclicBarrier(4, new Runnable() {
            @Override
            public void run() {
                System.out.println("All the players are ready, let's start the game!");
            }
        });

        Player player1 = new Player("Tom");
        Player player2 = new Player("Jerry");
        Player player3 = new Player("Mike");
        Player player4 = new Player("John");

        player1.start();
        player2.start();
        player3.start();
        player4.start();

        player1.join();
        player2.join();
        player3.join();
        player4.join();
    }

    static class Player extends Thread {
        private String name;

        public Player(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            try {
                System.out.println(name + " is preparing...");
                Thread.sleep(1000);
                cyclicBarrier.await();
                System.out.println(name + " starts running...");
                Thread.sleep(3000);
                cyclicBarrier.await();
                System.out.println(name + " is close to the finish line...");
                Thread.sleep(2000);
                cyclicBarrier.await();
                System.out.println(name + " crosses the finish line!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果如下:

Tom is preparing...
Jerry is preparing...
Mike is preparing...
John is preparing...
All the players are ready, let's start the game!
Tom starts running...
Mike starts running...
Jerry starts running...
John starts running...
Jerry is close to the finish line...
Mike is close to the finish line...
Tom is close to the finish line...
John is close to the finish line...
Jerry crosses the finish line!
Mike crosses the finish line!
Tom crosses the finish line!
John crosses the finish line!

上面的代码中,我们创建了一个CyclicBarrier实例,其参数parties为4,表示等待4个运动员准备就绪后开始比赛。在每一个运动员中,我们通过cyclicBarrier.await()将每一个运动员线程阻塞,直到所有运动员都到达同步点。当所有运动员都准备就绪后,CyclicBarrier的构造方法中指定的Runnable开始执行,打印出"All the players are ready, let's start the game!",同时所有阻塞的线程开始继续执行比赛流程。当每一阶段都完成后,所有线程再次被阻塞,等待其他线程完成当前阶段。最后一阶段完成后,所有线程将一起结束比赛。

通过这两个示例,我们可以看到CyclicBarrier的强大功能和使用方法,它可以方便地实现线程之间的同步控制,很好地提高了并发编程的效率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中的 CyclicBarrier详解 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • IntelliJ IDEA使用maven实现tomcat的热部署

    下面是IntelliJ IDEA使用maven实现tomcat的热部署的完整攻略: 一、前置条件 已经安装好IntelliJ IDEA和Apache Maven,并且配置好了环境变量。 已经配置好了Tomcat服务器。 准备好要开发的Java Web项目。 二、pom.xml配置 在项目根目录下的pom.xml文件中添加以下内容: <build>…

    Java 2023年5月19日
    00
  • java LinkedList类详解及实例代码

    Java LinkedList 类详解及实例代码 介绍 Java中的LinkedList类是一个双向链表的实现,是List接口的有序集合。LinkedList类提供了方便的操作链表的方法,可以很容易地实现添加、删除、插入以及访问节点等操作。 以下是创建一个LinkedList的示例: LinkedList<String> linkedList =…

    Java 2023年5月23日
    00
  • java 实现KMP算法

    Java实现KMP算法完整攻略 什么是KMP算法 KMP算法全称是Knuth-Morris-Pratt算法,是一个字符串查找算法,用于在一个字符串S中查找一个模式串P出现的位置。 KMP算法思想 KMP算法的思想是通过一个”部分匹配”的概念,当部分匹配发生后,可以知道一部分字符是匹配的,从而充分利用这个已知信息,避免从头再去比较已经比较过的字符。 KMP算法…

    Java 2023年5月18日
    00
  • Spring MVC Controller返回值及异常的统一处理方法

    下面我将为你详细讲解“Spring MVC Controller返回值及异常的统一处理方法”的完整攻略。 一、Controller返回值的处理 在Spring MVC框架中,Controller负责处理客户端的HTTP请求并响应相应的结果给客户端。当客户端请求到达Controller之后,Controller需要根据业务逻辑处理数据,并根据结果返回响应结果给…

    Java 2023年5月27日
    00
  • Java定时器Timer简述

    Java定时器(Timer)是Java提供的一种机制,用来执行定时任务。它允许你在一个特定的时间间隔内反复地,或者仅仅是一次性地,执行某个代码段。在本文中,我们将详细讲解Java定时器的使用,包括创建Timer对象、添加任务、设定任务执行间隔等。 创建Timer对象 首先,我们需要创建一个定时器Timer对象。可以使用如下代码来创建: Timer timer…

    Java 2023年6月1日
    00
  • spring-boot-plus V1.4.0发布 集成用户角色权限部门管理(推荐)

    Spring Boot Plus V1.4.0发布 Spring Boot Plus是一个基于SpringBoot的项目快速开发脚手架,版本 V1.4.0 提供了用户角色权限部门管理的集成,方便用户快速搭建管理后台。 安装 首先,我们需要安装Java和Maven,参考:- Java 安装教程- Maven 安装教程 Spring Boot Plus 是通过M…

    Java 2023年5月20日
    00
  • Spring-基于Spring使用自定义注解及Aspect实现数据库切换操作

    下面是详细讲解基于Spring使用自定义注解及Aspect实现数据库切换操作的完整攻略。 简介 随着项目规模的增大,往往需要使用多个数据库,每个库分配到不同的模块或者不同的服务。如何快速方便地切换数据库是我们需求的核心,本文主要介绍基于Spring使用自定义注解及Aspect实现数据库切换操作。 准备工作 首先需要安装Spring Framework,建议使…

    Java 2023年5月20日
    00
  • 教你使用idea搭建ssm详细教程(Spring+Spring Mvc+Mybatis)

    以下是使用Idea搭建SSM框架的详细教程,包括Spring、Spring MVC和MyBatis三个框架的整合。 环境准备 在开始之前,需要确保以下环境已经准备好: JDK 1.8或以上版本 Maven 3.0或以上版本 Tomcat 8.0或以上版本 IntelliJ IDEA 2018或以上版本 创建Maven项目 打开IntelliJ IDEA,选择…

    Java 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部