Cześć
W części 5 poświęconej temacie wątków omówiłem temat Locków. Przypominając, Lock to jeden z wielu mechanizmów, narzędzi służących do synchronizacji wątków. W całej serii zostały omówione już:
- synchronized: aby przeczytać post, kliknij tutaj.
- semaphore: aby przeczytać post, kliknij tutaj.
- lock: aby przeczytać post, kliknij tutaj.
Dzisiaj chciałbym przybliżyć Wam temat „CountDownLatch”, powszechniej znane pod hasłem: Latche, który również jest mechanizmem służącym do synchronizacji kodu / wątków.
Wstęp
Celem tego wpisu jest przybliżenie Wam klasy „CountDownLatch” w teorii oraz praktyce. Używając tej klasy możemy spowodować, ze wątek będzie blokowany do czasu, aż inne wątki wykonują konkretne zadanie.
Innymi słowy, CountDownLatch posiada specjalne pole licznika, które można dekrementować wedle naszych potrzeb. Licznik ten możemy następnie użyć do zablokowania wywołującego wątku, aż zostanie on odliczony do zera. W praktyce moglibyśmy zainicjować klasę „CountDownLatch” z taką samą wartością licznika, jaką mamy liczbę wątków które chcemy obsługiwać. Następnie po wywołaniu metody „countdown()” po zakończeniu każdego wątku mamy gwarancje, że wątek zależny wywołujący „await()” będzie blokował się do czasu, aż inne wątki zostaną zakończone.
Przykład praktyczny
Brzmi skomplikowanie? No to tradycyjnie poniżej prezentuję historię z życia. Na blogu o tematyce biegowej nie może zabraknąć przykładu sportowego. Co prawda sezon Formuły 1 dobiega już końca ale wyobraźmy sobie typowy wyścig. Zawodnicy startują zazwyczaj po tym, jak gasną czerwone światła. Nasz wyścig będzie trochę inny i chcemy, żeby nasi kierowcy wystartowali dopiero na jakiś inny konkretny znak. Naszym znakiem startowym w tym przypadku będzie metoda „countDown()” z klasy „CountDownLatch”.
Spójrzmy na kawałek kodu:
W powyższym przykładzie możemy zauważyć, że wykorzystując metode „sygnalStartowy.countDown()” dajemy możliwość naszym kierowcom rozpocząć ściganie się.
Na koniec natomiast nasz kod czeka, aż wszyscy zawodnicy dadzą znać, że swój wyścig ukończyli i dopiero wtedy możemy rozstrzygnąć wyniki. Dzięki mechanizmowi klasy „CountDownLatch” który pozwala nam ustalić liczbę naszych sygnałów (pozwolenie na starty), których oczekujemy, można w łatwy sposób zsynchronizować te zdarzenia.
W przypadku wystartowania naszego wyścigu, mamy do czynienia jedynie z jednym sygnałem, w który daje możliwość ścigania się wszystkim naszym kierowcom. Jednak wyścig możemy uznać za zakończony, kiedy dostaniemy tyle sygnałow, ile jest biegaczy. Dzięki temu będziemy mieć pewność, że dalszy mechanizm kodu (np. dekoracja) wykona się dopiero kiedy wszyscy kierowcy ukończą swój wyścig.
Podsumowanie
CountDownLatch jest wszechstronnym narzędziem synchronizacji i może być użyty do wielu celów – np. do testów współbieżności. Mechanizm ten świetnie sprawdza się, kiedy musimy osiągnąć synchronizację pomiędzy dwoma lub więcej wątkami. Zawsze możemy stworzyć wiele wątków ale rozpoczynać ich działanie dopiero na konkretny sygnał, dzięki czemu mamy pewność, że będą uruchamiane jednocześnie. W kolejnym wpisie programistycznym chciałbym poruszyć temat kolejnego mechanizmu synchronizacji wątków, czyli Barriery.
Pozdrawiam serdecznie,
biegajacyprogramista.pl