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日

相关文章

  • Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解

    下面是针对“Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解”的完整攻略。 什么是生产者消费者模式? 生产者消费者模式是指:生产者生产出来的任务放到一个仓库中,消费者从仓库中取出任务来消费。这样就将生产者和消费者融为一体,实现了解耦和。 生产者消费者模式需要解决的问题是:当仓库中的任务被消费完了,如何实现等待生产者生产新任务,同时也不影响已经在…

    多线程 2023年5月16日
    00
  • 详解Java高并发编程之AtomicReference

    详解Java高并发编程之AtomicReference 在Java高并发编程中,同步和锁机制都是非常基础的部分,但是它们的性能并不能够使我们满意。因此,Java也提供了一些新的并发原子操作类来避免这些问题。其中之一就是AtomicReference。 AtomicReference 基础 AtomicReference 是 Java 并发包中提供的一种原子化…

    多线程 2023年5月17日
    00
  • 详解Java并发编程之volatile关键字

    详解Java并发编程之volatile关键字 什么是volatile关键字? volatile 是 Java 中一个非常重要的关键字,用于修饰变量,可以保证多个线程操作同一个变量时的可见性。当一个变量被 volatile 修饰时,线程每次对这个变量进行操作后,都会强制刷新本地缓存,使其他线程可以立即获取到最新的值。 volatile关键字的作用 volati…

    多线程 2023年5月17日
    00
  • PHP 并发场景的几种解决方案

    下面是 PHP 并发场景的几种解决方案的完整攻略: 背景 PHP 是世界上最流行的 Web 开发语言之一。虽然 PHP 在 Web 开发中的应用非常广泛,但是其在并发编程场景下的表现较为差劣。在高并发情况下,PHP 程序往往会出现阻塞等问题,导致程序效率降低。 解决方案 为了解决 PHP 在并发编程场景下的问题,我们可以采用以下几种解决方案: 1. 多进程 …

    多线程 2023年5月16日
    00
  • python如何支持并发方法详解

    下面是关于Python如何支持并发方法的详解攻略。 1. 什么是并发? 并发是指一个系统可以同时处理多个任务的能力。Python中通过多线程和多进程两种方式实现并发编程。 2. Python的并发方法 2.1 多线程 Python中的多线程通过threading库实现。多线程可以在同一进程内分配不同任务给不同线程执行,从而提高程序的效率。 下面是一个基本的多…

    多线程 2023年5月16日
    00
  • 剖析Fork join并发框架工作窃取算法

    剖析Fork/Join并发框架工作窃取算法 什么是Fork/Join并发框架 Fork/Join并发框架是Java SE 7加入的一个用于并行执行任务的框架。这个框架的核心思想是:将一个大的任务拆分成若干个小任务分别执行,最后将执行结果汇总。 工作窃取算法 工作窃取算法(Work Stealing Algorithm)是Fork/Join并发框架中实现任务调…

    多线程 2023年5月17日
    00
  • SQL Server中事务和并发详解

    SQL Server中事务和并发详解 事务的概念 事务是指一组SQL语句组成的逻辑单元,这些SQL语句要么全部执行成功,要么全部执行失败,不能出现部分执行成功,部分执行失败的情况。在SQL Server中,事务由BEGIN TRANSACTION、COMMIT TRANSACTION和ROLLBACK TRANSACTION三个命令组成。 事务的特点 原子性…

    多线程 2023年5月16日
    00
  • java多线程编程之Synchronized关键字详解

    Java多线程编程之Synchronized关键字详解 什么是Synchronized关键字 Synchronized是一种Java中的关键字,可以将一段代码标记为“临界区”,保证多个线程在执行该代码时不会发生冲突,保证数据的正确性。 Synchronized关键字的用法 Synchronized关键字可以用在方法或代码块上。 用在方法上 public sy…

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