java多线程之CyclicBarrier的使用方法

Java多线程之CyclicBarrier的使用方法

简介

CyclicBarrier是Java多线程中的一个工具类,它可以用来构建可重用的同步对象,可以让一组线程在到达某个屏障时阻塞,直到所有的线程都到达屏障时,在继续执行。与CountDownLatch类似,都是多线程同步工具,但CyclicBarrier可以通过它的reset()方法,重用一次。

CyclicBarrier的构造方法如下:

public CyclicBarrier(int parties, Runnable barrierAction)

其中parties表示需要同步的线程数,barrierAction是当所有线程到达屏障时要执行的内容。

示例1

问题描述:假设有三个线程a、b、c,分别打印1、2、3,要求三个线程交替打印,现在使用CyclicBarrier来实现。

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierDemo {
    static CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
        @Override
        public void run() {
            System.out.println();
        }
    });
    static int count = 1;

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                        cyclicBarrier.await();
                        System.out.print(count++);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                        cyclicBarrier.await();
                        System.out.print(count++);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                        cyclicBarrier.await();
                        System.out.print(count++);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

以上代码定义了一个CyclicBarrier对象,该对象在初始化时指定了3个参与者和一个Runnable对象,在所有参与者到达屏障时会执行Runnable中的run方法。

三个线程各自启动并执行run方法,调用cyclicBarrier.await()方法来阻塞,直到所有线程都到达屏障,才会执行后续代码。

运行结果如下:

123
456
789
...

示例2

问题描述:定义三个线程,分别打印10个字母,可以多次循环打印,要求每次循环打印完毕后,等待一秒,再开始下一次循环,并使用CyclicBarrier来实现。

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierDemo2 {
    static CyclicBarrier cyclicBarrier = new CyclicBarrier(3);

    public static void main(String[] args) {
        final char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWX".toCharArray();
        for (int i = 0; i < 3; i++) {
            final int index = i;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    int count = 0;
                    while (true) {
                        try {
                            if (count == 3) {
                                System.out.println("Thread " + index + " finished printing " + count + " loops.");
                                cyclicBarrier.await();
                                count = 0;
                            }
                            Thread.sleep(1000);
                            for (int j = 0; j < 10; j++) {
                                System.out.print(chars[j + index * 10]);
                            }
                            System.out.println();
                            count++;
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
    }
}

以上代码用CyclicBarrier实现了一个循环打印字母的例子。

CyclicBarrier对象在初始化时指定了3个参与者,每个参与者都会执行run方法中的循环打印字母的代码。

当每个参与者打印完3次10个字母后,会调用cyclicBarrier.await()方法进入等待状态,直到所有参与者都完成后,才会让所有参与者同时开始下一轮打印。

控制台输出如下:

ABCDEFGHIJ
KLMNOPQRST
UVWXYZABCD
Thread 0 finished printing 3 loops.
ABCDEFGHIJ
KLMNOPQRST
UVWXYZABCD
Thread 1 finished printing 3 loops.
ABCDEFGHIJ
KLMNOPQRST
UVWXYZABCD
Thread 2 finished printing 3 loops.
...

总结

在使用CyclicBarrier时,需要设置参与者数和可重用的Runnable对象,在屏障处阻塞的线程可以调用await()方法一起等待,当所有线程都到达屏障处时,在执行Runnable对象中的任务。

CyclicBarrier是一个很有用的多线程同步工具,可以用于实现复杂的线程控制逻辑。在使用时,需要注意多线程的安全问题,如同步、死锁等问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java多线程之CyclicBarrier的使用方法 - Python技术站

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

相关文章

  • Redis处理高并发机制原理及实例解析

    Redis处理高并发机制原理及实例解析 简介 Redis是一种高性能的NoSQL存储,拥有高并发、高可用、高性能等特点。在现代web应用中,Redis已经成为了必不可少的组件之一。本文将详细介绍Redis处理高并发的机制原理,并结合实例进行说明。 Redis处理高并发的机制原理 Redis处理高并发的机制主要依靠以下两个方面: 基于单线程模型的高效执行 多种…

    多线程 2023年5月16日
    00
  • Java线程并发工具类CountDownLatch原理及用法

    Java线程并发工具类CountDownLatch原理及用法 简介 CountDownLatch是一种非常实用的java线程同步工具类,主要作用是允许一个或多个线程一直等待,在其他线程执行完一组操作之后才执行。 CountDownLatch主要有两个方法:* countDown() : 对计数器进行操作,将计数器的值减少1* await() : 调用该方法的…

    多线程 2023年5月16日
    00
  • 【java 多线程】守护线程与非守护线程的详解

    Java多线程:守护线程与非守护线程的详解 什么是守护线程? 在Java多线程中,守护线程是一种在后台运行的线程,它不会阻止程序的结束,也不会执行任何没有被其他非守护线程阻止的操作。 换句话说,当程序中最后一个非守护线程结束时,JVM会强制退出来,即使守护线程还在运行。 如何创建守护线程? 可以通过Thread类的setDaemon()方法来创建守护线程,示…

    多线程 2023年5月17日
    00
  • Java多线程之并发编程的基石CAS机制详解

    Java多线程之并发编程的基石CAS机制详解 什么是CAS CAS,即Compare And Swap,中文翻译为比较并交换。是一种无锁算法,用于实现多线程同步。在CAS操作中包含三个操作数:内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在CA…

    多线程 2023年5月16日
    00
  • 实例分析Java单线程与多线程

    实例分析Java单线程与多线程 Java线程(Thread)是程序执行的最小单元,可以在单线程和多线程两种模型中运行。单线程模型指该程序只有一个线程,而多线程模型则允许多个线程同时运行。在实际编程中,面对复杂的任务和高并发情况,多线程逐渐变得不可避免。因此,本文将详细讲解实例分析Java单线程与多线程的完整攻略。 Java单线程模型 在Java单线程模型下,…

    多线程 2023年5月17日
    00
  • 基于newFixedThreadPool实现多线程案例

    下面我来讲解一下基于newFixedThreadPool实现多线程的完整攻略。 一、ThreadPoolExecutor简介 在讲解newFixedThreadPool之前,先来介绍一下ThreadPoolExecutor。ThreadPoolExecutor是Java中的线程池框架,其实现了ExecutorService接口,可以通过线程池来管理多个线程,…

    多线程 2023年5月17日
    00
  • Java httpClient连接池支持多线程高并发的实现

    Java httpClient是一种开源的基于Http的请求和响应类型,它可以通过连接池技术适用于高并发的请求场景,下面是httpClient连接池支持多线程高并发的实现攻略: 1. 引入依赖 <dependency> <groupId>org.apache.httpcomponents</groupId> <art…

    多线程 2023年5月16日
    00
  • 关于dubbo 自定义线程池的问题

    关于 Dubbo 自定义线程池的问题,我们可以按照以下步骤进行攻略: 1. 了解 Dubbo 线程模型 在 Dubbo 中,每个服务提供者都会有线程池,用于处理消费者的请求。Dubbo 的线程模型分为以下两种: 共享线程池模型(默认):每个服务提供者使用一个全局的线程池处理所有请求; 独享线程池模型:每个服务提供者为每个消费者维护一个线程池,处理该消费者的所…

    多线程 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部