почему Countdownlatch в java останавливается при заданном количестве защелок? - PullRequest
0 голосов
/ 31 мая 2018
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Processor implements Runnable {
    private CountDownLatch latch;

    public Processor(CountDownLatch latch) {
        this.latch = latch;
    }

    public void run() {
        System.out.println("Started.");

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        latch.countDown();
    }
}
// -----------------------------------------------------

public class App {

    public static void main(String[] args) {

        CountDownLatch latch = new CountDownLatch(5); // coundown from 5 to 0

        ExecutorService executor = Executors.newFixedThreadPool(2); // 2 Threads in pool

        for(int i=0; i < 10; i++) {
            executor.submit(new Processor(latch)); // ref to latch. each time call new Processes latch will count down by 1
        }

        try {
            latch.await();  // wait until latch counted down to 0
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Completed.");
    }

}

Вывод:

Начинается Начинается Начинается Начинается Начинается Начинается Начинается Завершается` Начинается Начинается Начинается

В приведенном выше коде «Завершено» должно быть напечатано после 6 раз «Запущено» как защелкаОбратный отсчет до 5 - 0, почему это всегда 7 или 8 раз?Я правильно понял?

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Ваш пул потоков имеет размер 2, а выполнение потоков Processor занимает 3 секунды.

  • Первые два потока Processors запускаются, оба печатают Started, и они заканчивают 3 секундыпозже.
  • Затем запускаются следующие два и снова они оба печатают Started и заканчивают через 3 секунды.
  • Затем запускаются еще два (5-го и 6-го), печатаются Started и 3 секунды спустя, когда один из них (или оба) заканчивается.На данный момент есть несколько вещей, которые будут происходить примерно в одно и то же время (поэтому порядок является случайным):

    1. Основной поток возобновляет и печатает Completed
    2. 7 Processor нить запускается и печатает Started
    3. 8 Processor нить запускается и печатает Started

Следовательно, Completed всегда будет предшествовать 6, 7 или 8 Started распечаток.

0 голосов
/ 31 мая 2018

Итак, CountDownLatch не гарантирует, что он возобновит выполнение родительского потока (здесь я имею в виду поток, из которого вы вызвали latch.await();), как только обратный отсчет перейдет к 0.Итак, что произойдет, когда обратный отсчет защелки обратного отсчета до 0, что означает, что теперь родительский поток может возобновить свою работу, и это не значит, что он получит процессор тогда и там.Таким образом, это может возобновить, что не означает, что процессор планирует родительский поток, как только обратный отсчет времени до 0.Если есть другие потоки, то есть вероятность, что они могут выполняться перед родительским потоком. В вашем случае он гарантирует, что он не будет выполнять before 5 печать времени Started, но ensure будет exactly после печати 5 раз Started.Вы также можете наблюдать при определенном выполнении вашего кода Completed печатает в конце всей Started печати. ​​

...