1

私のプログラムでは、CountDownLatch await () メソッドはプログラムをブロックし続けます, CountDownLatch が書かれているように, カウントダウン ラッチです.カウントが 0 になると 3 つのスレッドの実行がトリガーされます.cdAnswer が 0 に減ると 3 つのスレッドが実行されたことを証明します.実行するメイン スレッドですが、私のプログラムでは、3 つのスレッドしか完了しません 2 つのメイン スレッドが実行されました。一番下が私のプログラムです。

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();

    }
}

問題補足: この結果は私が期待したものではありません。このタスクの結果は完了しました」は最終的な印刷物になります

写真は私のプログラムの結果を示しています。 ここに画像の説明を入力

4

1 に答える 1

2

これは、ランナブルの run メソッドが表示されるためです。

            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で2回呼び出され、catch句の前で1回呼び出されます。したがって、3 つのスレッドの場合、カウントダウンは 6 回呼び出され、その結果、メイン スレッドは 3 つのカウントダウンの後に開始されます。

cdAnswer.countDown(); を削除します。catch ステートメントのすぐ上で、期待どおりに機能します

于 2015-09-02T10:25:19.123 に答える