Czy ktoś może mi pomóc zrozumieć, czym CountDownLatch
jest Java i kiedy z niej korzystać?
Nie mam bardzo jasnego pojęcia o tym, jak działa ten program. Jak rozumiem, wszystkie trzy wątki zaczynają się od razu i każdy wątek wywoła CountDownLatch po 3000ms. Więc odliczanie zmniejszy się jeden po drugim. Gdy zatrzask zmieni się na zero, program wyświetli komunikat „Zakończono”. Może sposób, w jaki zrozumiałem, jest nieprawidłowy.
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(3); // coundown from 3 to 0
ExecutorService executor = Executors.newFixedThreadPool(3); // 3 Threads in pool
for(int i=0; i < 3; 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.");
}
}
Odpowiedzi:
Tak, zrozumiałeś poprawnie.
CountDownLatch
działa na zasadzie zatrzasku, główny wątek będzie czekał na otwarcie bramy. Jeden wątek czeka na n wątków określonych podczas tworzeniaCountDownLatch
.Każdy wątek, zwykle główny wątek aplikacji, którego wywołania
CountDownLatch.await()
będą czekać, aż liczba osiągnie zero lub zostanie przerwany przez inny wątek. Wszystkie pozostałe wątki muszą odliczać, dzwoniącCountDownLatch.countDown()
po ich ukończeniu lub gotowości.Gdy tylko liczba osiągnie zero, wątek oczekujący jest kontynuowany. Jedną z wad / zalet tego
CountDownLatch
jest to, że nie można go ponownie użyć: gdy liczba osiągnie zero, nie można już z niego korzystaćCountDownLatch
.Edytować:
Użyj,
CountDownLatch
gdy jeden wątek (jak główny wątek) wymaga oczekiwania na ukończenie jednego lub więcej wątków, zanim będzie mógł kontynuować przetwarzanie.Klasycznym przykładem użycia
CountDownLatch
w Javie jest aplikacja Java po stronie serwera, która korzysta z architektury usług, w której wiele usług jest udostępnianych przez wiele wątków, a aplikacja nie może rozpocząć przetwarzania, dopóki wszystkie usługi nie zostaną pomyślnie uruchomione.Pytanie PS OP ma całkiem prosty przykład, więc go nie uwzględniłem.
źródło
One thread waits for n number of threads specified while creating CountDownLatch in Java
. Jeśli potrzebujesz takiego mechanizmu, rozważne jest jego użycieCyclicBarrier
. Fundamentalna różnica koncepcyjna pomiędzy tymi dwoma, jak podano wJava concurrency in Practice
to:Latches are for waiting for events; barriers are for waiting for other threads
.cyclicBarrier.await()
przechodzi w stan blokowania.