CountDownLatch in Java

CountDownLatch allows one or more threads to wait for other threads to complete operations.

Suppose we have such a requirement now that we need to parse the data in a sheet. At this time, we can consider multi-threading, one thread parses a sheet, and after all threads have parsed the sheet, statistics are performed. For those who have learned multiple threads, we can think of using the join method to solve it.

public static void main(String[] args) throws InterruptedException {
    Thread t1 = new Thread(){
        @Override
public void run() {        
            System.out.println ( " Thread A parsing completed " ) ;
 }        
    };
    Thread t2 = new Thread(){
        @Override
public void run() {        
            System.out.println ( " Thread B parsing completed " ) ;
 }        
    } ;
     t1.start() ;
     t2.start() ;
     t1.join() ;
     t2.join() ;
 System.out     .println ( " All threads have been resolved " ) ;
 }

The above code is to start two threads to parse the sheet. When both thread 1 and thread 2 are executed, the output of all threads is completed.


It can be seen that all thread parsing is completed only after thread A and thread B are executed.

Here comes the problem, the join method is used to make the current thread wait for the execution of the join thread to end. Its implementation principle is to constantly check whether the join thread is alive. If the join thread is alive then let the current thread wait forever. Until the join thread is terminated, the thread's this.notifyAll method will be called to wake up other threads.

The CountDownLatch provided in the concurrent package of JDK1.5 can also implement the function of join, and has more functions than join.

Let's see how CountDownLatch is implemented

public static void main(String[] args) throws InterruptedException {
    CountDownLatch latch = new CountDownLatch(2);
    Thread t1 = new Thread(){
        @Override
public void run() {        
            System.out .println ( " Thread A parsing completed " ) ;
 latch .countDown () ;
 }                    
    };
    Thread t2 = new Thread(){
        @Override
public void run() {        
            System.out .println ( " Thread B parsing completed " ) ;
 latch .countDown () ;
 }                    
    } ;
     t1.start() ;
     t2.start() ;
     latch.await() ;
 System.out     .println ( " All threads have been resolved " ) ;
 }

The constructor of CountDownLatch accepts a parameter of type int as a counter. If you want to wait for N points to complete, pass in N here.

The await method is equivalent to a barrier, and all threads will be blocked outside the barrier until the N you pass in becomes 0. When the countDown method is called once, N will decrease by 1. When N becomes 0, the barrier disappears.

If a thread is slow to process, it is impossible for the main thread to wait all the time, so another await method with a specified time can be used. If the thread is not waited within the special time, the current thread will no longer be blocked.

getCount method

    CountDownLatch has a getCount method to get the number of how many more are needed to pass the barrier.

If you have a meeting now, let's say there are three people, it can only start when all three arrive

public class Test2 {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(3);
        System.out.println("准备开会,等待人员到齐");
        Thread t1 = new Thread(){
            @Override
            public void run() {
                System.out.println("你已经到了办公室");
                latch.countDown();
                System.out.println("还有"+latch.getCount()+"人没到");
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                System.out.println("他已经到了办公室");
                latch.countDown();
                System.out.println("还有"+latch.getCount()+"人没到");
            }
        };
        Thread t3 = new Thread(){
            @Override
            public void run() {
                System.out.println("我已经到了办公室");
                latch.countDown();
                System.out.println("还有"+latch.getCount()+"人没到");
            }
        };
        t1.start();
        t2.start();
        t3.start();
        latch.await();
        System.out.println("所有人都到齐了,开始开会");
    }
}

只有当三个人都到达时,才能开始开会。假设有一个来的比较迟呢,那我应该先开始开会,最后一个人来了之后参与其中。

public class Test2 {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(3);
        System.out.println("准备开会,等待人员到齐");
        Thread t1 = new Thread(){
            @Override
            public void run() {
                System.out.println("你已经到了办公室");
                latch.countDown();
                System.out.println("还有"+latch.getCount()+"人没到");
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("他已经到了办公室");
                latch.countDown();
                System.out.println("我来迟了,我们继续吧");
            }
        };
        Thread t3 = new Thread(){
            @Override
            public void run() {
                System.out.println("我已经到了办公室");
                latch.countDown();
                System.out.println("还有"+latch.getCount()+"人没到");
            }
        };
        t1.start();
        t2.start();
        t3.start();
        latch.await(3,TimeUnit.SECONDS);
        if (latch.getCount()>0){
            System.out.println("我们先开始开会");
        }else {
            System.out.println("所有人都到齐了,开始开会");
        }
    }
}

使用getCount和带参数的await即可以实现这种情况。

总结:

   在CountDownLatch对象时需要传入一个int类型的N值,将CountDownLatch.await当做门的话,这个值就代表了需要多少力量才能打开门。可以使用getCount来获得你还需要多少力量才能打开门。每次调用countDown就会将你传入的N减一,如果await方法判断N为0,则门消失。当N不为0时,所有线程都会被挡在门外,为了避免主线程一直等待,可以使用带参数的await方法,当等待指定时间后门还未打开,则门也消失。


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325685011&siteId=291194637