Wątki – synchronizacja wątków czyli Lock

Wątki – synchronizacja wątków czyli Lock

Cześć

   W części 4 poświęconej temacie wątków omówiłem temat Semaphore. Przypominając, Semaphore to jeden z wielu mechanizmów, narzędzi służących do synchronizacji kodu. W całej serii zostały omówione już:

Dzisiaj chciałbym przybliżyć Wam temat Locka, który również jest mechanizmem służącym do do synchronizacji kodu.

Locki

    Locki są mechanizmem synchronizacji wątków, takim jak bloki synchronizowane, z tą różnicą, że Locki dają programiście większe możliwości do działania, są bardziej elastyczne. Od Javy 5 java.util.concurrent.locks zawiera kilka implementacji Locków. Locki są tworzone przy użyciu bloków synchronizowanych, więc nie jest tak, że możemy całkowicie pozbyć się słowa kluczowego synchronized.

Różnice pomiędzy Lock oraz blokiem Synchronized

  • wątek zostaje zablokowany, jeśli nie może uzyskać dostępu do bloku synchronized. W przypadku Lock, API udostępnia metodę tryLock(). Wątek jest zablokowany tylko wtedy, gdy jest ona dostępna i nie jest w posiadaniu żadnego innego wątku. Zmniejsza to czas blokowania wątku oczekującego na zablokowanie
  • blok synchronized jest w oparty w jednej metodzie. W przypadku Lock, API udostępnia metodę lock() oraz unlock() w oddzielnych metodach
  • wątek, który jest w stanie oczekiwania na uzyskanie dostępu do bloku synchronized, nie może zostać przerwany. W przypadku Lock, API dostarcza metodę lockInterruptibly(), która być użyta do przerwania wątku, gdy ten oczekuje na blokadę

ReadWriteLock

     Poza podstawowym interfejsem Lock, możemy spotkać również sub-interfejs, który nazywa się ReadWriteLock. Jak sama nazwa wskazuje, interfejs ten utrzymuje parę blokad. Jedną dla operacji odczytu, a drugą dla operacji zapisu. Blokada odczytu może być jednocześnie utrzymywana przez wiele wątków tak długo, jak długo nie ma zapisu.

Interfejs ReadWriteLock deklaruje metody służące do uzyskiwania blokad odczytu lub zapisu:

  • readLock() – zwraca blokadę, która jest używana do odczytu
  • writeLock() – zwraca blokadę, która jest używana do zapisu

Przykład praktyczny

Chciałbym omówić przykład praktyczny dotyczący mechanizmu Lock oraz jego subinterfejsu ReadWriteLock. 

Przykład praktyczny ReadWriteLock. www.biegajacyprogramista.pl

Zaimplementowano klasę SamochodInfo, w której mamy dwie metody: pobierzCene() i ustawCene(). W przypadku drugiej metody, mamy do czynienia z synchronizacją writeLocka. W praktyce oznacza to, że dozwolony jest dostęp tylko dla jednego wątku. Podczas uzyskania locka, żaden inny wątek nie skorzysta wówczas z metody włóż, ani z metody odczytaj.

Pierwszazaimplementowana metoda  wykorzystuje readLocka. Tutaj w praktyce oznacza to, że wiele wątków jednocześnie może skorzystać z tej metody. Uwaga! Kiedy jakiś wątek wywoła metodę pobierz, wtedy readLock nie może zostać wywołany.

Podsumowując, w momencie modyfikacji ceny samochodu, tylko jeden wątek może korzystać z tej metody. W momencie czytania ceny, dostęp może mieć wiele wątków.

Podsumowanie

     Na pierwszy rzut oka, blok Synchronized a Lock mogą wydawać się identyczne. Idea tych mechanizmów rzeczywiście jest taka sama, lecz w praktyce to właśnie Lock jest bardziej elastyczne i udostępnia więcej metod do zarządzania wątkami, co widać na omówionym przykładzie. Locki znajda idealne zastosowanie w klasach, w których więcej razy trzeba będzie wykonać akcję odczytu, aniżeli liczbę zapisu. Dzięki zastosowaniu różnych rodzaju Lock’ów można uzyskać większą wydajnośc danej klasy. W kolejnym wpisie programistycznym chciałbym poruszyć temat kolejnego mechanizmu synchronizacji wątków, czyli Barriery.

Pozdrawiam serdecznie,
biegajacyprogramista.pl

Dodaj komentarz

16 − nine =

Close Menu