How to use CyclicBarrier in Java - Concurrency Tutorail(转)

本文详细介绍了Java中的CyclicBarrier类,包括其原理、如何使用以及何时使用。通过一个具体的例子展示了四个工作线程等待彼此到达某个点后再开始再次运行的过程。此外,文章还探讨了CyclicBarrier在并发编程中的实际应用,如编写并发测试、模拟并发环境以及计算多个任务完成后结果等。同时,解释了如何重用CyclicBarrier对象,以及如何在Java 7及以上版本中捕获多个异常在一个catch块中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

This is the second part of my concurrency tutorial, in  first part , you have learned how to use CountDownLatch  and in this part, you will learn  how to use CyclicBarrier class in Java . CyclicBarrier  is another concurrency utility introduced in Java 5 which is used when a number of threads (also known as parties) wants to wait for each other at a common point, also known as barrier before starting processing again. Its similar to  CountDownLatch  but instead of calling  countDown() each thread calls  await()  and when last thread calls  await()  which signals that it has reached barrier, all thread started processing again, also known as barrier is broken. You can use  CyclicBarrier wherever you want to use  CountDownLatch , but opposite is not possible because you can not reuse the latch once count reaches to zero. Some of the common usage of  CyclicBarrier  is in writing unit test for concurrent program, to simulate concurrency in test class or calculating final result after  individual  task has completed. 

In this tutorial, I will  show  you an example of how four worker thread waits for other before starting again. As I told in previous  article , concurrency is hard to master, sometime even if you read couple of articles on one topic, you don't get what you are looking for. If you understand how and where to use CountDownLatch  and  CyclicBarrier , then only you will feel confident. Books are also good for mastering concurrency, and one book in particular is very useful to learn multi-threading and concurrency in Java. You guessed it right, I am talking about  Java Concurrency in Practice by Brian Goetz , I strongly recommend this book to anyone seriously wants to master threading and concurrency in Java. If you can't get first hand, get second hand, if you can't buy then lend it from library but if you are serious about Java concurrency, you should read it.



CyclicBarrier Example in Java

You just cannot understand concurrency without an example, seeing is believing here. It's difficult to comprehend words like worker thread, parties, waiting for each other at a point, until you see it live in action. In this program, we have four worker threads and one main thread, which is running your main method. We have an  object  of  CyclicBarrier , which is initialized with parties = 4, the argument we passed in  CyclicBarrier  constructor is nothing but number of party, which is actually number of threads to stop at barrier. The barrier will not be broken until all parties are arrived. A party (thread) is said to be arrived with it call  barrier.await()  method.

How to use CyclicBarrier in Java


In our example setup, we have given each worker thread a different name, starting from PARTY-1 to PARTY-4 just to have a meaningful output. We have passed same instance of cyclic barrier to each thread. If you look at their  Runnable implementation , you will find that each party sleep for some seconds and then call  await()  method on barrier. The sleep is introduced so that every thread calls barrier method after some time.  Sleep time is also on increasing order, which means PARTY-4 should be the last one to call await. So as per our theory, every thread (party) should wait after calling  await()  until the last thread (PARTY-4) calls the  await()  method, after that every thread should wake up and start processing. Of-course they need to compete for CPU and they will start running once they got the CPU from thread scheduler, but what is more important is that once barrier is broken, each thread (party) becomes eligible for  scheduling . By the way, you can reuse the barrier even after its broken this is where  CyclicBarrier is different than CountDownLatch .

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

/**
 * Java Program to demonstrate how to use CyclicBarrier, Its used when number of threads
 * needs to wait for each other before starting again.
 * 
 * @author Javin Paul
 */
public class HelloHP {

    public static void main(String args[]) throws InterruptedException, BrokenBarrierException {
        
        CyclicBarrier barrier = new CyclicBarrier(4);
        Party first = new Party(1000, barrier, "PARTY-1");
        Party second = new Party(2000, barrier, "PARTY-2");
        Party third = new Party(3000, barrier, "PARTY-3");
        Party fourth = new Party(4000, barrier, "PARTY-4");
        
        first.start();
        second.start();
        third.start();
        fourth.start();
        
        System.out.println(Thread.currentThread().getName() + " has finished");

    }

}

class Party extends Thread {
    private int duration;
    private CyclicBarrier barrier;

    public Party(int duration, CyclicBarrier barrier, String name) {
        super(name);
        this.duration = duration;
        this.barrier = barrier;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(duration);
            System.out.println(Thread.currentThread().getName() + " is calling await()");
            barrier.await();
            System.out.println(Thread.currentThread().getName() + " has started running again");
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

Output
main has finished
PARTY-1 is calling await()
PARTY-2 is calling await()
PARTY-3 is calling await()
PARTY-4 is calling await()
PARTY-4 has started running again
PARTY-1 has started running again
PARTY-2 has started running again
PARTY-3 has started running again

If you look at the output is exactly matches with our theory. Each worker thread (PARTY 1 - 3) calls the await()  method and then they stop processing until  PARTY-4  comes and call  await()  method, after that every thread gets a wake up call and started execution again, depending upon when they are scheduled by Java thread scheduler. This is how  CyclicBarrier  class works. You can still reuse the barrier  object  and if a thread calls  barrier.await()  again, it will wait for four worker thread before it gets wake up call. By the way,  If barrier is broken before a thread calls  await()  then this method will throw  BrokenBarrierException .


When to use CyclicBarrier in Java Program

It is a very useful class and have several practical uses. You can use this to perform final task once  individual task are completed. You can use it to write some unit tests to check some variants as well. Remember you can reuse the barrier as opposed to latch.  One a side note, this  CyclicBarrier  example is also a good example of how to catch multiple exception in one catch block in Java,  a feature introduced in JDK 1.7 . You can see that we have two unrelated exceptions  InterruptedException  and  BrokenBarrierException , but we have caught then in same catch block, because of this feature, this code requires Java 7 to run. If you are not using JDK 7 then just use two catch block instead of one.

Java CyclicBarrier Example


That's all about how to use CyclicBarrier in Java. In this CyclicBarrier Example you have not only learned  how to use CyclicBarrier but also when to use it. You should use it when one thread needs to wait for a fixed number of thread before starting an event e.g. Party. You can use CyclicBarrier to write concurrency unit test and implement generic algorithms in Java

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值