Use of CountDownLatch, Cyclic Barrier, Semaphore

Posted by defx on Thu, 03 Oct 2019 22:19:13 +0200

Count Down Latch

CountDownLatch (Countdown Counter, Block) lets some threads block until others complete some operations before they are awakened

CountDownLatch has two main methods: when one or more threads call the await() method, the calling thread will be blocked; when other threads call the countDown() method, the counter will be subtracted by one, and the countDown() method will not be blocked.

When the value of the counter is 0, the thread blocked by calling await() method is awakened

public class CountDownLatchTest {

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        for(int i = 0; i < 5; i++){
            new Thread(()->{
                try {
                    TimeUnit.SECONDS.sleep(1);//Sleep for 1 second
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "\t thread");
                countDownLatch.countDown(); //Counter minus one
            }, String.valueOf(i)).start();
        }

        countDownLatch.await();//When the counter is 0, wake up the thread
        System.out.println(Thread.currentThread().getName() + "\t thread");
    }

}

Result:

II. Cyclic Barrier

Cyclic Barrier, which blocks a group of threads when they reach a barrier (synchronization point), does not open until the last thread reaches the barrier and the thread continues to execute.

public class CyclicBarrierTest {
    public static void main(String[] args) {
//        CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3, ()->{
            System.out.println(Thread.currentThread().getName() + "\t work");
        });
        for(int i = 0; i < 6; i++){
            new Thread(()->{
                System.out.println(Thread.currentThread().getName() + "\t begin");
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "\t end");
            }, String.valueOf(i)).start();
        }

    }
}

Result:

III. Semaphore

Semaphore (semaphore) is mainly used for two purposes, one is for the mutually exclusive interaction of multiple shared resources, and the other is for the control of the number of concurrent threads.

public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3);//Simulate three parking spaces
        for(int i = 0; i < 6; i++){//Simulate six cars
            new Thread(()->{
                try {
                    semaphore.acquire();
                    int time = (int)(1+Math.random()*(10-1+1));
                    System.out.println(Thread.currentThread().getName() + "\t Grab the parking space, Use"+time+"second");
                    TimeUnit.SECONDS.sleep(time);
                    System.out.println(Thread.currentThread().getName() + "\t Leaving the parking space");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                }
            }, String.valueOf(i)).start();
        }

    }
}

Result: