W Javie używamy semafora w synchronizacji wątków. Jest on używany do kontroli dostępu do współdzielonego zasobu, który używa zmiennej licznika. Java dostarcza również klasę Semaphore, która zawiera konstruktory i różne metody do kontrolowania dostępu do współdzielonego zasobu. Omówimy to w dalszej części tej sekcji.

Przed przejściem do dalszej części tej sekcji, najpierw zrozumiemy, co to jest semafor, typy semaforów, jak to działa i jak zaimplementować semafor. Po zapoznaniu się z tym wszystkim, przejdziemy do programów semaforowych w Javie.

Co to jest semafor?

Semafor jest używany do ograniczenia liczby wątków, które chcą uzyskać dostęp do współdzielonego zasobu. Innymi słowy, jest to nieujemna zmienna, która jest współdzielona między wątkami znanymi jako licznik. Wyznacza ona granicę liczby wątków. Mechanizm, w którym wątek czeka na semaforze, może być sygnalizowany przez inne wątki.

  • Jeśli licznik > 0, dostęp do współdzielonych zasobów jest zapewniony.
  • Jeśli licznik = 0, dostęp do współdzielonych zasobów jest odrzucany.

W skrócie, licznik śledzi liczbę uprawnień, które nadał do współdzielonego zasobu. Dlatego semafor przyznaje pozwolenie wątkom na współdzielenie zasobu.

Charakterystyka semafora

Istnieją następujące cechy semafora:

  • Zapewnia synchronizację między wątkami.
  • Zmniejsza poziom synchronizacji. Stąd zapewnia niskopoziomowy mechanizm synchronizacji.
  • Semafor nie zawiera wartości ujemnej. Trzyma wartość, która może być większa od zera lub równa zeru.
  • Możemy zaimplementować semafor używając operacji testowej i przerwania, a do jego wykonania używamy deskryptorów plików.

Działanie semafora

Semafor kontroluje współdzielony zasób poprzez zmienną licznika. Licznik jest wartością nieujemną. Zawiera wartość albo większą od 0, albo równą 0.

  • Jeśli licznik > 0, wątek uzyskuje pozwolenie na dostęp do współdzielonego zasobu, a wartość licznika jest dekrementowana o 1.
  • W przeciwnym razie wątek zostanie zablokowany, dopóki nie będzie można uzyskać pozwolenia.
  • Gdy wykonanie wątku zostanie zakończone, wtedy nie ma potrzeby korzystania z zasobu i wątek go zwalnia. Po zwolnieniu zasobu wartość licznika zwiększa się o 1.
  • Jeśli inny wątek oczekuje na pozyskanie zasobu, wątek w tym czasie pozyska zezwolenie.
  • Jeśli licznik = 0, wątek nie otrzymuje zezwolenia na dostęp do współdzielonego zasobu.

Zrozummy działanie semafora za pomocą schematu blokowego.

Semafor Javy

Typy semaforów

Istnieją cztery typy semaforów, które są następujące:

  • Semafory zliczające
  • Semafory ograniczone
  • Semafory czasowe
  • Semafory binarne

Semafor Java

Przedyskutujmy szczegółowo jeden po drugim.

Semafory zliczające

Semafory zliczające są używane do rozwiązania sytuacji, w której więcej niż jeden proces chce wykonać się w sekcji krytycznej, jednocześnie. Stąd, aby przezwyciężyć ten problem używamy semaforów zliczających. Na przykład, rozważmy następujący wycinek kodu.

Zobaczmy implementację semaforów zliczających.

CountingSemaphoresExample.java

Semafory ograniczone

Możemy ustawić górną granicę przy użyciu semaforów ograniczonych. Jest on używany zamiast semaforów zliczających, ponieważ semafory zliczające nie zawierają żadnej górnej wartości granicznej. Górna wartość graniczna określa, ile sygnałów może przechowywać. Na przykład, rozważ następujący wycinek kodu.

Zobaczmy implementację semafora ograniczonego.

BoundedSemaphoresExample.java

Semafory czasowe

Semafory czasowe pozwalają wątkowi działać przez określony czas. Po upływie określonego czasu, timer resetuje się i zwalnia wszystkie inne zezwolenia.

Zobaczmy implementację semaforów czasowych.

TimedSemaphoresExample.java

Semafory binarne

Semafory binarne są takie same jak semafory zliczające. Należy jednak pamiętać, że akceptują one tylko wartości binarne albo 0 albo 1. Jego implementacja jest prosta w porównaniu do innych semaforów. Jeśli wartość wynosi 1, operacja sygnalizacyjna kończy się sukcesem, w przeciwnym razie kończy się niepowodzeniem.

Zobaczmy implementację semaforów binarnych.

BinarySemaphoresExample.java

Semafor w Javie

W Javie jest to konstrukcja synchronizacji wątków. Konstrukcja ta wykorzystuje zmienną znaną jako licznik, która kontroluje dostęp do współdzielonego zasobu. Jest to typ zmiennej, która jest używana do zarządzania współbieżnymi procesami, a także do ich synchronizacji. Jest on również używany do unikania warunków wyścigu. Ogranicza liczbę wątków do dostępu do współdzielonego zasobu.

Na przykład, możemy ograniczyć dostęp do pliku do 10 połączeń jednocześnie.

Java Semaphore Class

Java dostarcza klasę Semaphore do implementacji mechanizmu semaforów. Należy ona do pakietu java.util.concurrent. Implementuje ona interfejs Serializable. Stąd nie jest wymagana ręczna implementacja.

Klasa Semafor udostępnia następujące dwa konstruktory:

  • Semaphore(int permits)
  • Semaphore(int permits, boolean fair)

Semaphore(int permits)

Tworzy Semafor i parsuje liczbę zezwoleń (początkową liczbę dostępnych zezwoleń) jako argument. Określa liczbę wątków, które mogą współdzielić zasób w danym momencie. Wartość zezwoleń może być ujemna. W takim przypadku musi nastąpić zwolnienie, zanim zostaną przyznane jakiekolwiek przejęcia.

Syntaktyka:

Semaphore(int permits, boolean fair)

Tworzy semafor z podaną liczbą zezwoleń i podanymi ustawieniami sprawiedliwości.

Syntaktyka:

Przetwarza dwa parametry:

  • permits: Wartość permits może być ujemna. W takim przypadku zwolnienie musi nastąpić, zanim zostaną przyznane jakiekolwiek nabycia.
  • fair: Jeśli ustawimy wartość na true, semafor gwarantuje FIFO wątkom w kolejności, w jakiej są żądane, false Domyślnie wszystkie wątki, które oczekują na zasoby przyznają zezwolenia w niezdefiniowanej kolejności.

Metody klasy Semafor

Klasa udostępnia następujące metody:

acquire() Metoda: Metoda pozyskuje zezwolenia z semafora, blokując do czasu, aż jedno będzie dostępne, lub wątek zostanie przerwany. Zmniejsza ona liczbę dostępnych zezwoleń o 1.

Jeżeli dla bieżącego wątku nie jest dostępne żadne zezwolenie, wątek staje się nieaktywny dla celów planowania wątków. Bieżący wątek przechodzi w stan nieaktywny, dopóki nie wydarzy się jedna z dwóch rzeczy:

  • Jeśli inny wątek wywoła metodę release(), aby zwolnić zasób, wtedy bieżący wątek otrzyma zezwolenia.
  • Jeśli inny wątek przerwie bieżący wątek.

Wyrzuca wyjątek InterruptedException, jeśli bieżący wątek zostanie przerwany. Metoda nie zwraca żadnej wartości.

Syntaktyka:

metodarelease(): Zwalnia zezwolenie i zwraca je na semafor. Zwiększa liczbę dostępnych zezwoleń o 1. Jeśli jakiś wątek próbuje nabyć zezwolenie, semafor udziela zezwolenia na nabycie zasobu, który został właśnie zwolniony przez inne wątki. Ponadto, wątek ten jest brany pod uwagę przy planowaniu wątków.

Syntaktyka:

availablePermits() Metoda: Metoda zwraca liczbę dostępnych w semaforze zezwoleń na przyznanie zasobu. Zazwyczaj jest ona używana do debugowania i testowania.

Syntax:

Zrozummy powyższe metody na prostym przykładzie.

Używanie semafora jako blokady

Java pozwala nam używać semafora jako blokady. Oznacza to, że blokuje on dostęp do zasobu. Każdy wątek, który chce uzyskać dostęp do zablokowanego zasobu, musi wywołać metodę acquire() przed uzyskaniem dostępu do zasobu, aby uzyskać blokadę. Wątek musi zwolnić blokadę wywołując metodę release(), po zakończeniu zadania. Pamiętaj, że ustaw górną granicę na 1. Na przykład, rozważmy następujący fragment kodu:

Zobaczmy przykład semafora i użyjmy semafora jako blokady.

SemaphoreAsLock.java

Wyjście:

Java Semaphore

Uwaga: Kiedy wykonujemy powyższy program, za każdym razem otrzymujemy inne dane wyjściowe. Tak więc, twoje wyjście może się różnić od tego pokazanego powyżej.

Przykład semafora Java

Zrozummy mechanizm semafora poprzez program w Javie. W poniższym przykładzie utworzyliśmy konstruktor klasy Semaphore z początkową wartością zezwolenia 3.

SemaphoreExample.java

Wyjście:

Java Semaphore
.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.