Демонстрационная программа CountdownLatch. Не дожидаясь завершения защелки отсчета

В этой программе, почему сообщение All countdownlatch over печатается между ними. Хотя оно должно дождаться завершения всех защелок обратного отсчета. Поскольку дополнительный поток запускается в основном методе, но это должно обрабатываться как вызов метода cdl.countDown() для обрабатывать обратный отсчет для этой темы. Почему нарушается защелка обратного отсчета?

import java.util.concurrent.CountDownLatch;

public class CDLDemo implements Runnable {

    static int count = 0;

    CountDownLatch cdl = new CountDownLatch(5);

    void checkForAwait() {
        cdl.countDown();
        System.out.println("Start " + cdl.getCount());
        CDLTask1 cdlTask1 = new CDLTask1(cdl);
        CDLTask2 cdlTask2 = new CDLTask2(cdl);
        CDLTask3 cdlTask3 = new CDLTask3(cdl);
        CDLTask4 cdlTask4 = new CDLTask4(cdl);

        Thread t1 = new Thread(cdlTask1);
        Thread t2 = new Thread(cdlTask2);
        Thread t3 = new Thread(cdlTask3);
        Thread t4 = new Thread(cdlTask4);

        t1.start();
        t2.start();
        t3.start();
        t4.start();
        try {
            cdl.await();
            System.out.println("All countdownlatch over");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void run() {
        checkForAwait();
    }

    public static void main(String[] args) throws InterruptedException {
        CDLDemo cdlDemo = new CDLDemo();
        Thread t1 = new Thread(cdlDemo, "Thread1");
        t1.start();
        t1.join();
        System.out.println("All completed");
    }

    static int getCount() {
        return count++;
    }


    static class CDLTask1 implements Runnable {
        CountDownLatch cdl;

        public CDLTask1(CountDownLatch cdl) {
            this.cdl = cdl;
        }

        @Override
        public void run() {
            getCount();
            cdl.countDown();
            System.out.println("Available count :" + cdl.getCount() + "" + Thread.currentThread().getName());
        }
    }

    static class CDLTask2 implements Runnable {
        CountDownLatch cdl;

        public CDLTask2(CountDownLatch cdl) {
            this.cdl = cdl;
        }

        @Override
        public void run() {
            cdl.countDown();
            System.out.println("Available count :" + cdl.getCount() + "" + Thread.currentThread().getName());
        }
    }

    static class CDLTask3 implements Runnable {
        CountDownLatch cdl;

        public CDLTask3(CountDownLatch cdl) {
            this.cdl = cdl;
        }

        @Override
       public void run() {
            cdl.countDown();
            System.out.println("Available count :" + cdl.getCount() + "" + Thread.currentThread().getName());
        }
    }

    static class CDLTask4 implements Runnable {
        CountDownLatch cdl;

        public CDLTask4(CountDownLatch cdl) {
            this.cdl = cdl;
        }

        @Override
        public void run() {
            cdl.countDown();
            System.out.println("Available count :" + cdl.getCount() + "" + Thread.currentThread().getName());
        }
    }

}

person Sidhant Pant    schedule 14.08.2020    source источник


Ответы (1)


Ваш оператор печати в CDLTask находится после cdl.countDown(), поэтому вы получаете сообщение между ними. Поток может быть вытеснен между операторами обратного отсчета и печати, тогда ваш основной может быть просигнализирован до того, как будут выполнены все отпечатки.

person Cyril G.    schedule 14.08.2020
comment
есть ли способ контролировать его, чтобы он не мог быть вытеснен и ждать, пока защелка обратного отсчета не достигнет 0, а затем только мой основной поток печатает System.out.println (все завершено); - person Sidhant Pant; 22.08.2020