Latching CountDownLatch and CyclicBarrier

There is some synchronization knowledge that is not commonly used but I think it will be very useful. Here I refer to other people's articles and my own understanding, and briefly describe the uses and differences between locks and fences.

Latches: A synchronization helper class that allows one or more threads to wait until a set of operations that are being performed in other threads are completed. That is, a group of threads wait for an event to occur. Before the event occurs, all threads will block and wait; after the event occurs, all threads will start executing; the lock is initially closed, and the lock will be opened after the event occurs. , the latch will always be open.

    CountDownLatch(int count) is the only constructor of the latch CountDownLatch. When the countDown() method is called on the latch, the latch counter will be decremented by 1. When the latch counter is 0, the latch will be opened and all threads will start executing through the latch.


Barrier: A synchronization helper class that allows a group of threads to wait on each other until some common barrier point is reached. With fences, threads can be made to wait for each other until all threads reach a certain point, then the fence will open and all threads will continue execution through the fence. CyclicBarrier supports an optional Runnable parameter, the runnable object will be called when the thread passes through the barrier. Constructor CyclicBarrier(int parties, Runnable barrierAction), when the thread calls the await() method on the CyclicBarrier object, the counter of the barrier will be incremented by 1, and when the counter is parties, the barrier will be opened.


Difference: Locking is used for all threads to wait for an external event to occur; Fence is that all threads wait for each other until all threads reach a certain point before opening the fence, and then threads can continue to execute.

Example: Quoted from http://aaron-han.iteye.com/blog/1591755

1. There are five people, one referee. These five people ran at the same time, the referee started timing, all five people reached the finish line, the referee called to stop, and then counted how long it took these five people to run from the beginning to the last collision line.
import java.util.concurrent.CountDownLatch;    
    
public class Race {    
    
    public static void main(String[] args) {    
        final int num = 5;    
        final CountDownLatch begin = new CountDownLatch(1);    
        final CountDownLatch end = new CountDownLatch(num);    
    
        for (int i = 0; i < num; i++) {    
            new Thread(new AWorker(i, begin, end)).start();    
        }    
    
        // judge prepare...    
        try {    
            Thread.sleep((long) (Math.random() * 5000));    
        } catch (InterruptedException e1) {    
            e1.printStackTrace();    
        }    
    
        System.out.println("judge say : run !");    
        begin.countDown();    
        long startTime = System.currentTimeMillis();    
    
        try {    
            end.await();    
        } catch (InterruptedException e) {    
            e.printStackTrace ();    
        } finally {    
            long endTime = System.currentTimeMillis();    
            System.out.println("judge say : all arrived !");    
            System.out.println("spend time: " + (endTime - startTime));    
        }    
    
    }    
    
}    
    
class AWorker implements Runnable {    
    final CountDownLatch begin;    
    final CountDownLatch end;    
    final int id;    
    
    public AWorker(final int id, final CountDownLatch begin,    
            final CountDownLatch end) {    
        this.id = id;    
        this.begin = begin;    
        this.end = end;    
    }    
    
    @Override    
    public void run() {    
        try {    
            System.out.println(this.id + " ready !");    
            begin.await();    
            // run...    
            Thread.sleep((long) (Math.random() * 10000));    
        } catch (Throwable e) {    
            e.printStackTrace ();    
        } finally {    
            System.out.println(this.id + " arrived !");    
            end.countDown();    
        }    
    }    
    
}

2. Continue, these five people (these five people are so boring..), this time there is no referee. It is stipulated that as long as all five people reach the finish line, everyone can drink beer. However, as long as one person does not reach the finish line, they cannot drink. There is also no requirement for everyone to start at the same time (of course, you can add a latch).
import java.util.concurrent.BrokenBarrierException;  
import java.util.concurrent.CyclicBarrier;  
  
public class Beer {  
  
    public static void main(String[] args) {  
        final int count = 5;  
        final CyclicBarrier barrier = new CyclicBarrier(count, new Runnable() {  
            @Override  
            public void run() {  
                System.out.println("drink beer!");  
            }  
        });  
  
        // they do not have to start at the same time...  
        for (int i = 0; i < count; i++) {  
            new Thread(new Worker(i, barrier)).start();  
        }  
    }  
  
}  
  
class Worker implements Runnable {  
    final int id;  
    final CyclicBarrier barrier;  
  
    public Worker(final int id, final CyclicBarrier barrier) {  
        this.id = id;  
        this.barrier = barrier;  
    }  
  
    @Override  
    public void run() {  
        try {  
            System.out.println(this.id + "starts to run !");  
            Thread.sleep((long) (Math.random() * 10000));  
            System.out.println(this.id + "arrived !");  
            this.barrier.await();  
        } catch (InterruptedException e) {  
            e.printStackTrace ();  
        } catch (BrokenBarrierException e) {  
            e.printStackTrace ();  
        }  
    }  
}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326940331&siteId=291194637