Co to jest Java Semaphore i Mutex – Java Concurrency MultiThread wyjaśnione na przykładzie

Opublikowany: 2015-03-12

Samouczek Java Mutex i Semaphore autorstwa Crunchify

Współbieżność Java to bardzo szeroki temat. Dostępne są setki samouczków i przykładów. Jakiś czas temu napisałem kilka samouczków na temat uruchamiania wielu wątków jednocześnie w Javie i różnych typów zsynchronizowanych bloków.

W tym samouczku omówimy:

  1. Wyjaśnienie Mutex
  2. Wyjaśnienie semafora
  3. Dwa przykłady ze szczegółami

Zacznijmy

Let's keep this in mind czytając poniższe wyjaśnienie:

  • Weź przykład Kupującego i Klienta
  • Kupujący pożycza laptopy
  • Klient może przyjść i skorzystać z laptopa – klient potrzebuje klucza do korzystania z laptopa
  • Po użyciu – klient może zwrócić laptopa do Kupującego

Co to jest Mutex (tylko 1 wątek):

Kupujący ma klucz do laptopa. Jeden klient może mieć klucz – pożyczyć laptopa – w tym czasie. Po zakończeniu zadania Klient oddaje (uwalnia) klucz kolejnemu klientowi w kolejce.

Official Definition :

„Mutex jest zwykle używany do serializacji dostępu do sekcji re-entrant code , który cannot be executed concurrently przez więcej niż jeden wątek. Obiekt mutex pozwala tylko na jeden wątek w kontrolowanej sekcji, zmuszając inne wątki, które próbują uzyskać dostęp do tej sekcji, do czekania, aż pierwszy wątek opuści tę sekcję.”

Innymi słowy: Mutex = Mutually Exclusive Semaphore

Co to jest Semafor (N określonych wątków):

Załóżmy, że teraz Shopper ma 3 identyczne laptopy i 3 identyczne klucze. Semafor to liczba free identical Laptop keys . Liczba semaforów – liczba kluczy – jest na początku ustawiona na 3 (wszystkie trzy laptopy są wolne), a następnie wartość licznika jest zmniejszana w miarę przychodzenia Klienta. Jeśli wszystkie laptopy są w użyciu, tj. nie ma wolnych kluczy dla Laptop, liczba semaforów wynosi 0. Teraz, gdy któryś z klientów zwraca Laptop, semafor jest zwiększany do 1 (jeden wolny klucz) i przekazywany następnemu klientowi w kolejce.

Official Definition : „Semafor ogranicza liczbę jednoczesnych użytkowników współdzielonego zasobu do maksymalnej liczby. Wątki mogą żądać dostępu do zasobu (zmniejszanie semafora) i mogą sygnalizować, że zakończyły korzystanie z zasobu (zwiększenie semafora).”

Kolejna musi przeczytać: Lazy Creation of Singleton ThreadSafe Instance

Przykład-1: (wyjaśnienie poniżej)

W powyższym samouczku CrunchifySemaphoreMutexTutorial.java , gdy CrunchifyProducer dodaje threadName do obiektu crunchifyList crunchifyList, może to sygnalizować semafor.

CrunchifyConsumer może wtedy próbować uzyskać semafor, więc będzie czekał, aż CrunchifyProducer zasygnalizuje dodanie threadID. Po zasygnalizowaniu dodanych danych jeden z konsumentów zostanie obudzony i będzie wiedział, że może odczytać obiekt crunchifyList. Może przeczytać listę, a następnie wrócić do próby zdobycia semafora.

Jeśli w tym czasie producent napisał kolejny pakiet, zasygnalizował ponownie, a następnie jeden z konsumentów odczyta kolejny pakiet i tak dalej…

Innymi słowy:

Wynik:

Jak zapobiec sytuacji wyścigu:

What if you have multiple Consumers? W powyższym samouczku Java Konsumenci (nie producenci) powinni blokować bufor podczas odczytu pakietu (ale nie podczas uzyskiwania semafora), aby zapobiec sytuacji wyścigu. W poniższym przykładzie producent również blokuje listę, ponieważ wszystko jest na tej samej JVM.

Przykład-2:

Wynik: