Talk about high concurrency (30) parsing java.util.concurrent each component (12) Understanding Cyclicbarrier Fence

Source: Internet
Author: User
Tags volatile

This is about the cyclicbarrier fence, which can be seen from its name, which is recyclable. It functions like Countdownlatch, and also lets a group of threads wait, and then begin to execute down together. But there are still a few differences between the two.

1. The waiting object is different. A group of Countdownlatch threads waits for an event, or a counter that is 0. The cyclicbarrier waits for the thread, and only the thread is there to go down.

2. Using different methods, this is also caused by waiting for the object, Countdownlatch need to call await () to let the thread wait, call Countdown () to modify the state until a state of 0 is triggered by the event. The cyclicbarrier only needs to call await () to let the thread wait, and when the number of threads calling the await () method satisfies the condition, it automatically wakes all threads down

3. Cyclicbarrier can be automatically recycled, and when an intercept is opened, the next intercept is automatically created. Countdownlatch counter cannot be used again after 0

4. The underlying implementation is different, Countdownlatch uses AQS to achieve the underlying synchronization, cyclicbarrier based on the upper Reetrantlock + condition condition Queue implementation

5. The failure mechanism is different, and the thread waiting on Countdownlatch will not affect other threads if it is interrupted or the timeout is canceled. and cyclicbarrier adopt all-or-none mechanism, either all do not pass, or all pass, that is, once the thread waiting in the cyclicbarrier is interrupted or the timeout is canceled, So all the other threads waiting in this cyclicbarrier are woken up and executed down through the fence

6. Cyclicbarrier supports the callback function after all the threads pass through, passing in a Runnable object, executed by the last arriving thread. And Countdownlatch does not support callback mechanisms


Here's a look at Cyclicbarrier's source code, which has an internal class generation to handle the problem of recycling, maintaining a broker state that indicates whether the current fence is invalidated. If it fails, the state of the fence can be reset. When the fence is broken, the broker that sets the current generation is true to fail, and wakes up all waiting threads, the all-or-none mechanism

private static Class Generation {        Boolean broken = false;    }        private void Nextgeneration () {//Signal completion of last generation Trip.signalall ();        Set up next generation count = parties;    Generation = new Generation ();        }private void Breakbarrier () {Generation.broken = true;        Count = parties;    Trip.signalall (); }


Maintains a reentrantlock to synchronize and creates a related conditional queue condition, using the condition await () method to let threads wait in the same condition queue, using Condition.signalall () Wakes all the threads that are waiting through a conditional queue.

/** the lock for guarding barrier entry *    /private final reentrantlock lock = new Reentrantlock ();    /** Condition to wait on until tripped *    /private final Condition trip = Lock.newcondition ();

Maintains a runnable to support callback functions

/* The command to run when tripped *    /private final Runnable barriercommand;public cyclicbarrier (int parties, Runnable        Barrieraction) {if (parties <= 0) throw new IllegalArgumentException ();        This.parties = parties;        This.count = parties;    This.barriercommand = barrieraction; }

A count is maintained to count when the await () method is called once, and Count is reduced by 1 until count is 0 to open the fence.

private int count;

You can see that the instance properties of Cyclicbarrier are not using volatile variables, so how does it guarantee the visibility of the state? The cyclicbarrier uses the Ga Xian-lock method. We know that explicit and built-in locks guarantee visibility, ordering, and atomicity.

1. Enter the lock equivalent to read volatile, will empty the CPU cache, forcing read from memory

2. Leave the lock equivalent to write volatile, the CPU write buffer data will be forced to flush to memory


Cyclicbarrier often supports common waits and time-limited waits. Finally, the Dowait () method is dropped.

public int await () throws Interruptedexception, Brokenbarrierexception {        try {            return dowait (false, 0L);        } catch (timeoutexception toe) {            throw new Error (toe);//cannot happen;        }    }               public int await (long timeout, timeunit unit) throws Interruptedexception, Brokenbarrierexception,    timeoutexception {return dowait (true, Unit.tonanos (timeout)); }

Look at the Dowait method.

1. Locks must be acquired first to ensure visibility, ordering, atomicity

2. Determine the status of the current fence, if it has failed, throw brokerbarrierexception exception

3. If the thread is interrupted, then the fence is deactivated, and all waiting threads are awakened to execute.

4. Execute the dowait once to count minus one, with index record the current thread execution is the count value as indexed

5. If index = = 0 indicates the last thread to arrive, the fence can be opened. First, if there is a callback, the callback is executed. Then reset the fence state so that it can be recycled, returning 0

6. If index is not 0, indicating that it is not the last thread to arrive, polling waits, where the time-limited operation is supported, using the await () mechanism of the condition conditional queue. Until the time-out or the fence is normally invalidated. When a fence fails, it uses condition to wake up all the threads waiting in the same condition queue.

private int Dowait (Boolean timed, Long Nanos) throws Interruptedexception, Brokenbarrierexception, Ti        meoutexception {final Reentrantlock lock = This.lock;        Lock.lock ();            try {final Generation g = Generation;            if (g.broken) throw new Brokenbarrierexception ();                if (thread.interrupted ()) {breakbarrier ();            throw new Interruptedexception ();           } int index =--count;               if (index = = 0) {//tripped Boolean ranaction = false;                   try {final Runnable command = Barriercommand;                   if (command! = null) Command.run ();                   Ranaction = true;                   Nextgeneration ();               return 0;               } finally {if (!ranaction) breakbarrier (); }}//loop until tripped, BrokEn, interrupted, or timed out for (;;)                    {try {if (!timed) trip.await ();                else if (Nanos > 0L) Nanos = Trip.awaitnanos (Nanos);                        } catch (Interruptedexception IE) {if (g = = Generation &&! G.broken) {                        Breakbarrier ();                    throw ie; } else {//we ' re about-to-finish waiting even if We had not//been Interru                        Pted, so this interrupt are deemed to//"belong" to subsequent execution.                    Thread.CurrentThread (). interrupt ();                }} if (G.broken) throw new Brokenbarrierexception ();                if (g! = generation) return index; If (timed && Nanos <= 0L) {breakbarrier ();                throw new TimeoutException ();        }}} finally {Lock.unlock (); }    }

The following test case is used to test the functionality of the Cyclicbarrier

1. Create a 5-capacity cyclicbarrier and set the callback

2. Running 12 threads

Package Com.lock.test;import Java.util.concurrent.cyclicbarrier;public class Cyclicbarrierusecase {private Cyclicbarrier barrier = new Cyclicbarrier (5, new Runnable () {@Overridepublic void run () {System.out.println ("Callback is R Unning ");}); public void Race () throws Exception{system.out.println ("Thread" + thread.currentthread (). GetName () + ' is waiting the res Ource "); barrier.await (); System.out.println ("Thread" + thread.currentthread (). GetName () + "got the Resource");} public static void Main (string[] args) {final cyclicbarrierusecase usecase = new Cyclicbarrierusecase (); for (int i = 0; I &l T 12; i++) {Thread t = new Thread (new Runnable () {@Overridepublic void run () {try {usecase.race ()} catch (Exception e) {//TODO A Uto-generated catch Blocke.printstacktrace ();}}, String.valueof (i)); T.start ();}}}

Test results:

1. You can see that 5 threads are waiting until a full 5 thread arrives and the fence is opened, and the 5 threads execute down and execute the callback

2. The fence is recycled and 5 threads wait until the 5 threads reach and open the fence and execute the callback

3. The fence is recycled, but only 2 threads, less than 5, have been waiting

Thread 0 is waiting the Resourcethread 4 is waiting the Resourcethread 5 are waiting the Resourcethread 3 is waiting the RE  Sourcethread 2 is waiting the Resourcecallback are Runningthread 1 is waiting the Resourcethread 0 got the Resourcethread 2 Got the Resourcethread 6 is waiting the Resourcethread 7 are waiting the Resourcethread 4 got the Resourcethread 9 is wait ing the Resourcethread 8 is waiting the Resourcethread 3 got the Resourcethread 5 got the Resourcecallback is Runningthrea D 8 got the Resourcethread 1 got the Resourcethread 7 got the Resourcethread 6 got the Resourcethread is waiting the RE Sourcethread waiting the Resourcethread 9 got the resource

Talk about high concurrency (30) parsing java.util.concurrent each component (12) Understanding Cyclicbarrier Fence

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.