Проблемы с методом CountDownLatch await()?

В моей программе метод CountDownLatch await () будет продолжать блокировать программу, CountDownLatch в том виде, в котором он написан, Является ли отсчет обратного отсчета, когда отсчет до нуля запускает три потока, и доказать, что три, когда cdAnswer уменьшен до 0 потока, были выполнены, тогда Основной поток выполнить, но в моей программе три потока только завершаются Два основных потока были выполнены, кто может мне помочь, я был бы очень благодарен. Внизу моя программа.

public class CountdownLatchTest {
    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();
        final CountDownLatch cdOrder = new CountDownLatch(1);
        final CountDownLatch cdAnswer = new CountDownLatch(3);

        for (int i = 0; i < 3; i++) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("Thread" + Thread.currentThread().getName()
                                + "Wait for the command");

                        cdOrder.await();
                        System.out.println("Thread" + Thread.currentThread().getName()
                                + "received command");
                        Thread.sleep((long) (Math.random() * 10000));
                        System.out.println("Thread" + Thread.currentThread().getName()
                                + "Feedback the results");
                        cdAnswer.countDown();
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        System.out.println("To complete the order");
                        cdAnswer.countDown();

                    }
                }
            };
            service.execute(runnable);
        }
        try {
            Thread.sleep((long) (Math.random() * 10000));

            System.out.println("Thread" + Thread.currentThread().getName()
                    + "The upcoming orders");
            cdOrder.countDown();
            System.out.println("Thread" + Thread.currentThread().getName()
                    + "Sent the command, are waiting for the result");
            cdAnswer.await();
            System.out.println("Thread" + Thread.currentThread().getName()
                    + "Have received all the response. "
                    + "The results of this task has been completed");
        } catch (Exception e) {
            e.printStackTrace();
        }
        service.shutdown();

    }
}

Дополнение к задаче: Этот результат не тот, который я ожидал, я подумал, что это предложение "Получил весь ответ. Результаты этой задачи были выполнены 'будут в окончательном виде

На картинке показан результат моей программы. введите описание изображения здесь

1 ответ

Решение

Это потому, что если вы видите метод run вашего runnable

            public void run() {
                try {
                    System.out.println("Thread"
                            + Thread.currentThread().getName()
                            + "Wait for the command");

                    cdOrder.await();
                    System.out.println("Thread"
                            + Thread.currentThread().getName()
                            + "received command");
                    Thread.sleep((long) (Math.random() * 10000));
                    System.out.println("Thread"
                            + Thread.currentThread().getName()
                            + "Feedback the results");
                    cdAnswer.countDown(); -- countdown on latch cdAnswer
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    System.out.println("To complete the order");
                    cdAnswer.countDown(); -- countdown on latch cdAnswer

                }
            }

cdAnswer.countDown(); вызывается дважды для каждого работоспособного, одного в finally и одного до предложения catch. Таким образом, для трех потоков обратный отсчет вызывается шесть раз, в результате основной поток начинается после 3 обратного отсчета.

Удалить cdAnswer.countDown(); чуть выше поймать заявление это работает, как ожидалось

Другие вопросы по тегам