preface

CountDownLatch applies to scenarios

  • A main task consists of multiple sub-tasks
  • The main task must wait for the subtask to complete before continuing

Under normal circumstances, the main thread does not wait for child threads

  • code
class CountDownLatchT2 {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = () -> {
            try {
                Thread.sleep(2000);// Thread sleep
                System.out.println("hello world");
            } catch(InterruptedException e) { e.printStackTrace(); }}; IntStream.range(0.4).forEach(i -> new Thread(runnable).start());// Start 4 threads
        System.out.println("Child thread started up");
        System.out.println("Main thread completed"); }}Copy the code

Using CountDownLatch

public class CountDownLatchT {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(4);// Create an instance of CountDownLatch, usually with the number of child threads
        Runnable runnable = ()-> {
            try {
                Thread.sleep(2000);
                System.out.println("hello world");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                countDownLatch.countDown();// The number of threads that the child thread has run is reduced by 1 until 0}}; IntStream.range(0.4).forEach(i ->new Thread(runnable).start());
        System.out.println("Child thread started up");
        countDownLatch.await();// The main thread waits
        System.out.println("Main thread completed"); }}Copy the code

General process and principles of CountDownLatch

Code meaning

CountDownLatch source

  • A synchronization assist that allows one or more threads to wait until a set of operations performed in another thread is complete.
  • CountDownLatchClass with the given count. Because of the callcountDownMethod,awaitThe method blocks until the present momentCount to zeroAnd thenRelease all waiting threadsAnd any subsequent onesawaitThe call will return immediately. This is a one-off phenomenon — the count cannot be reset. If you need to reset the version of the count, consider using itCyclicBarrier

Await () method

  • Causes the current thread to wait until the latch countdown reaches zero, unless the thread is interrupted.
  • If the current count is zero, this method returns immediately.
  • If the current count is greater than zero, the current thread is disabled for thread scheduling purposes and sleeps until one of two things happens:
    • Because the countDown method is called, the count reaches zero; or
    • Some other thread interrupts the current thread.
  • If the current thread:
  • Set the middle off state when entering this method; or
    • Interrupted while waiting,

    InterruptedException is then thrown and the interrupted status of the current thread is cleared.

CountDown () method

  • Decrement the count of the latch, and if the count reaches zero, all waiting threads are released.
  • Decrement if the current count is greater than zero. If the new count is zero, all waiting threads are re-enabled for thread scheduling purposes.
  • If the current count is zero, nothing happens.
  • countDown()The general principle is as follows:

Await (long timeout, TimeUnit Unit) method

  • Causes the current thread to wait until the latch countdown reaches zero, unless the thread is interrupted or the specified wait time has expired.
  • If the current count is zero, this method immediately returns true.
  • If the current count is greater than zero, the current thread is disabled for thread scheduling purposes and sleeps until one of three things happens:
    • Because the countDown method is called, the count reaches zero; or
    • Some other threads interrupt the current thread; or
    • The specified wait time has expired.
  • This method returns true if the count reaches zero.
  • If the current thread:
    • Set the middle off state when entering this method; or
    • Interrupted while waiting,

    InterruptedException is then thrown and the interrupted status of the current thread is cleared.

  • Returns false if the specified wait time has elapsed. If the time is less than or equal to zero, the method does not wait at all.

Parameter: timeout – Maximum time to wait Unit – Time unit of the timeout parameter Returned value: true if the count reaches zero and false if the wait time passes before the count reaches zero

This method prevents the main thread (main task) from waiting indefinitely

Example (infinite wait situation)

public class CountDownLatchT {
    public static void main(String[] args) throws InterruptedException {
        // Create an instance of CountDownLatch, usually with the number of child threads
        CountDownLatch countDownLatch = new CountDownLatch(5);
        Runnable runnable = ()-> {
            try {
                Thread.sleep(2000);
                System.out.println("hello world");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                countDownLatch.countDown();// The child thread completes the number of threads -1 up to 0}}; IntStream.range(0.4).forEach(i ->new Thread(runnable).start());
        System.out.println("Child thread started up");
        countDownLatch.await();// The main thread waits
        System.out.println("Main thread completed"); }}Copy the code

Example (useawait(long timeout, TimeUnit unit))

public class CountDownLatchT {
    public static void main(String[] args) throws InterruptedException {
        // Create an instance of CountDownLatch, usually with the number of child threads
        CountDownLatch countDownLatch = new CountDownLatch(5);
        Runnable runnable = ()-> {
            try {
                Thread.sleep(2000);
                System.out.println("hello world");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                countDownLatch.countDown();// The child thread completes the number of threads -1 up to 0}}; IntStream.range(0.4).forEach(i ->new Thread(runnable).start());
        System.out.println("Child thread started up");
        countDownLatch.await(2001, TimeUnit.MILLISECONDS);// The main thread waits
        System.out.println("Main thread completed"); }}Copy the code

The main thread will not wait indefinitely