CountDownLatch Java Concurrency of tools and CyclicBarrier

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/ThinkWon/article/details/102556958

Countdown CountDownLatch

After the multithreaded collaborate on business functions, sometimes need to wait for multiple threads to complete other tasks, the main thread can continue down the business functions in this business scenario, you can usually use the Thread class join method, let the Lord after a thread waiting to be join the thread executing the main thread to continue down the implementation. Of course, the use of inter-thread messaging mechanisms may also be done. In fact, Java concurrency utilities classes provide a similar "Countdown" such tools as we can be very convenient to complete said this business scenario.

To be able to understand CountDownLatch, give a very popular example, when athletes running race, assuming that there are six players involved in the game, the referee will split time as six players in the end, it is conceivable time whenever a player reaches the end, for the referee it is less of a timed task. Until all athletes reach the finish line, the referee's task to complete. The six athletes may be assimilated into six thread, when the thread calls CountDownLatch.countDown method will be on the value of the counter is decremented by one, until the time counter is 0, the referee (invoked await thread) to continue down carried out.

Let's look at some of the important methods CountDownLatch.

CountDownLatch start of construction method looks:

public CountDownLatch(int count)

Constructor will pass an integer N, CountDownLatch after calling the countDownmethod will reduce a N, N until the time reaches zero, called the current awaitmethod of thread to continue.

CountDownLatch approach is not a lot, enumerated them one by one:

  1. await () throws InterruptedException: the calling thread until the constructor method of the incoming N reaches zero time in order to continue down;
  2. await (long timeout, TimeUnit unit): consistent with the above features await method, but here with the time limit, the calling thread of the method after a specified timeout time to wait, regardless of whether N was reduced to zero, will continue down ;
  3. countDown (): CountDownLatch make the initial value N is decremented by 1;
  4. long getCount (): Gets the value of the current CountDownLatch maintenance;

Below with a specific example to illustrate the specific use of a CountDownLatch:

public class CountDownLatchDemo {

    private static CountDownLatch startSignal = new CountDownLatch(1);
    //用来表示裁判员需要维护的是6个运动员
    private static CountDownLatch endSignal = new CountDownLatch(6);

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(6);
        System.out.println("各位运动员准备啦!!!");
        for (int i = 0; i < 6; i++) {
            executorService.execute(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + " 运动员等待裁判员响哨!!!");
                    // 确保所有运动员准备完毕
                    Thread.sleep(1000);
                    startSignal.await();

                    System.out.println(Thread.currentThread().getName() + " 正在全力冲刺");
                    endSignal.countDown();
                    System.out.println(Thread.currentThread().getName() + " 到达终点");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        //将executorService转换为ThreadPoolExecutor,ThreadPoolExecutor有方法 getActiveCount()可以得到当前活动线程数
        int threadCount = ((ThreadPoolExecutor)executorService).getActiveCount();
        if (threadCount == 6) {
            System.out.println("裁判员响哨...");
            startSignal.countDown();

            endSignal.await();
            System.out.println("所有运动员到达终点,比赛结束!");
        }


        executorService.shutdown();
    }

}

Output

各位运动员准备啦!!!
pool-1-thread-1 运动员等待裁判员响哨!!!
pool-1-thread-3 运动员等待裁判员响哨!!!
pool-1-thread-2 运动员等待裁判员响哨!!!
pool-1-thread-5 运动员等待裁判员响哨!!!
pool-1-thread-4 运动员等待裁判员响哨!!!
pool-1-thread-6 运动员等待裁判员响哨!!!
裁判员响哨...
pool-1-thread-5 正在全力冲刺
pool-1-thread-5 到达终点
pool-1-thread-6 正在全力冲刺
pool-1-thread-2 正在全力冲刺
pool-1-thread-2 到达终点
pool-1-thread-1 正在全力冲刺
pool-1-thread-1 到达终点
pool-1-thread-3 正在全力冲刺
pool-1-thread-3 到达终点
pool-1-thread-4 正在全力冲刺
pool-1-thread-6 到达终点
pool-1-thread-4 到达终点
所有运动员到达终点,比赛结束!

The example code CountDownLatch two sets, a first endSignalfor controlling so that the main thread (referee) must wait until the other thread (players) so CountDownLatch maintained until the value of N is reduced to 0. Another startSignalfor the main thread to make "orders" to other threads, startSignal cited CountDownLatch initial value of 1, and run the other thread of execution method will first pass startSignal.await()are blocked so that these threads until the main thread by calling startSignal.countDown();, value N minus 1, the value N 0 after a CountDownLatch maintenance, other threads to execute down and, RUN method of each thread of execution will pass endSignal.countDown();to endSignalmaintain a reduced numerical values, since the thread pool to six tasks submitted, It will be minus 6 times, so endSignalmaintaining the value will eventually become zero, so the main thread in the latch.await();blocked end, to continue down the implementation.

Also, note that when you call countDown CountDownLatch method, the current thread is not blocked, it will continue down, such as output will continue in this example pool-1-thread-4 到达终点.

Cycling fence CyclicBarrier

CyclicBarrier is also a multi-threaded utility concurrency control, and has the same function CountDownLatch wait count, but compared to CountDownLatch more powerful.

To understand CyclicBarrier, a popular example cited here. When open the Games, which will run a campaign, we simulate the case when the next parade of athletes, suppose you have six runways, at the start of the game, you need 6 players at the start of the race starting point stood up, after the referee blows the whistle to start running. Runway starting point is equivalent to "barrier", it is the critical point, and that six athletes thread into the analogy, then, is this six threads must reach the designated point, meaning cobble together a wave, before proceeding, otherwise each thread had blocked waiting until you can scrape together Qi Yibo. cyclic circulation is meant, that CyclicBarrier when multiple threads to cobble together after wave, is still valid, we can continue to cobble together the next wave. CyclicBarrier schematic performed as follows:

Here Insert Picture Description

When multiple threads have reached a designated point, to continue down to continue. It's a bit like the feeling of the number of reported, suppose six threads on the equivalent of six athletes, will be reported when the number of statistics to the track starting point, if the words are just 6 of this wave to cobble together to perform down. CyclicBarrier after using once, the following is still valid, you can continue to use as a counter, which is one of the CountDownLatch difference . Here six threads, i.e. the initial value of the counter 6, by the constructor CyclicBarrier incoming.

The main method of CyclicBarrier look at the following:

//等到所有的线程都到达指定的临界点
await() throws InterruptedException, BrokenBarrierException 

//与上面的await方法功能基本一致,只不过这里有超时限制,阻塞等待直至到达超时时间为止
await(long timeout, TimeUnit unit) throws InterruptedException, 
BrokenBarrierException, TimeoutException 

//获取当前有多少个线程阻塞等待在临界点上
int getNumberWaiting()

//用于查询阻塞等待的线程是否被中断
boolean isBroken()

//将屏障重置为初始状态。如果当前有线程正在临界点等待的话,将抛出BrokenBarrierException。
void reset()

Also note that, CyclicBarrier provide such a constructor:

public CyclicBarrier(int parties, Runnable barrierAction)

It can be used when specifying the thread reaches the specified critical point, the operation can be performed next can be passed by the barrierAction.

one example

Below a simple example to us at the above example modeled by athletes, we look at the usage of CyclicBarrier.

public class CyclicBarrierDemo {

    //指定必须有6个运动员到达才行
    private static CyclicBarrier barrier = new CyclicBarrier(6, () ->
            System.out.println("所有运动员入场,裁判员一声令下!!!!!")
    );

    public static void main(String[] args) {
        System.out.println("运动员准备进场,全场欢呼............");

        ExecutorService service = Executors.newFixedThreadPool(6);
        for (int i = 0; i < 6; i++) {
            service.execute(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + " 运动员,进场");
                    barrier.await();
                    System.out.println(Thread.currentThread().getName() + "  运动员出发");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            });
        }
    }

}

Output

运动员准备进场,全场欢呼............
pool-1-thread-1 运动员,进场
pool-1-thread-4 运动员,进场
pool-1-thread-3 运动员,进场
pool-1-thread-2 运动员,进场
pool-1-thread-6 运动员,进场
pool-1-thread-5 运动员,进场
所有运动员入场,裁判员一声令下!!!!!
pool-1-thread-5  运动员出发
pool-1-thread-1  运动员出发
pool-1-thread-6  运动员出发
pool-1-thread-3  运动员出发
pool-1-thread-2  运动员出发
pool-1-thread-4  运动员出发

As can be seen from the output, when six players (threads) have reached a critical point specified (barrier) time to continue down, otherwise, it will block waiting for the call await()at

CountDownLatch comparison with the CyclicBarrier

CountDownLatch tools are used to control concurrent with CyclicBarrier, can be understood as a counter is maintained, but the two still have different emphases:

  1. After CountDownLatch A generally used for a thread to wait several other threads executing the task, it was executed; and CyclicBarrier generally used for a group of threads waiting for each other to a certain state, then this group of threads again performed simultaneously; CountDownLatch emphasize a thread and many other threads to complete something. CyclicBarrier multiple threads is reciprocal, so we are complete, then go hand in hand.
  2. After calling countDown CountDownLatch method of, and does not block the current thread, it will continue down; and calling the CyclicBarrier await method, will block the current thread until the specified thread CyclicBarrier all reached the designated point of time, to continue down carried out;
  3. CountDownLatch less method, the operation is relatively simple, while providing more CyclicBarrier method, such as through getNumberWaiting (), isBroken () method to get the current status of the plurality of threads, and can be passed CyclicBarrier constructor barrierAction , specifies all threads are executed when reaching the business function;
  4. CountDownLatch is not reusable, and CyclicLatch can be multiplexed.

Guess you like

Origin blog.csdn.net/ThinkWon/article/details/102556958