Co to jest muteks i semafor w Javie? Jaka jest główna różnica?


Odpowiedzi:


115

Semafor można policzyć, podczas gdy muteks może liczyć tylko do 1.

Załóżmy, że masz uruchomiony wątek, który akceptuje połączenia klientów. Ten wątek może obsługiwać 10 klientów jednocześnie. Następnie każdy nowy klient ustawia semafor, aż osiągnie 10. Kiedy semafor ma 10 flag, twój wątek nie będzie akceptował nowych połączeń

Muteksy są zwykle używane do ochrony rzeczy. Załóżmy, że 10 klientów ma dostęp do wielu części systemu. Następnie możesz zabezpieczyć część systemu za pomocą muteksu, więc gdy 1 klient jest podłączony do tego podsystemu, nikt inny nie powinien mieć dostępu. Do tego celu możesz również użyć semafora. Muteks to „Semafor wzajemnego wykluczenia” .


4
To nie jest do końca prawdą. Ten sam wątek może wejść do tego samego muteksu więcej niż jeden raz, więc należy zachować liczbę, aby zapewnić zrównoważenie wpisów i wyjść.
finnw

1
@finnw, ogólnie istnieją dwa typy muteksów, rekurencyjne i nierekurencyjne. Czy Java domyślnie używa typu rekurencyjnego?
edA-qa mort-ora-y

2
@ edA-qa mort-ora-y, termin „Mutex” nie jest używany w specyfikacji maszyny wirtualnej Java ani specyfikacji API, więc zakładam, że odnosi się do monitora wbudowanego w każdy obiekt, który jest również podobny do obiektu Win32 zwanego Mutex . To samo dotyczy a ReentrantLock. Wszystkie te są rekurencyjne. Nie znam żadnych przykładów nierekurencyjnych muteksów z „prawdziwego świata” (widziałem je tylko w podręcznikach), więc ich nie rozważałem.
finnw

2
Nierekurencyjne muteksy można zaimplementować przy użyciu semafora z liczbą jeden. Może to być przydatne, jeśli chcesz zapobiec wywołaniom rekurencyjnym. Ma to praktyczne zastosowanie, osobiście używałem go w dużych projektach do wykrywania pętli w kodzie inicjalizacyjnym (A inicjuje B, który próbuje ponownie zainicjować A).
Alexander Torstling

1
W standardzie C ++ 11 (C ++ 0x) muteks nie jest rekurencyjny. Zapewniają również oddzielny „recursive_mutex” dla tych, którzy tego potrzebują. Wiem, że mówimy tutaj o Javie, ale wielu z nas programuje teraz w różnych językach.
Aditya Kumar Pandey,

139

Niestety wszyscy przeoczyli najważniejszą różnicę między semaforem a muteksem; pojęcie „ własności ”.

Semafory nie mają pojęcia własności, co oznacza, że ​​każdy wątek może zwolnić semafor (może to prowadzić do wielu problemów samo w sobie, ale może pomóc w „wykrywaniu śmierci”). Podczas gdy mutex ma pojęcie własności (tj. Możesz zwolnić mutex, który nabyłeś).
Własność jest niezwykle ważna dla bezpiecznego programowania systemów współbieżnych. Zawsze zalecałbym używanie muteksu zamiast semafora (ale ma to wpływ na wydajność).

Muteksy mogą również obsługiwać dziedziczenie priorytetów (co może pomóc w rozwiązaniu problemu inwersji priorytetów) i rekursję (eliminując jeden typ zakleszczenia).

Należy również podkreślić, że istnieją semafory „binarne” i semafory „liczące / ogólne”. Semafor Javy jest semaforem zliczającym, dzięki czemu można go zainicjować wartością większą niż jeden (podczas gdy, jak wskazano, muteks może liczyć tylko jeden). Na przydatność tego wskazano w innych postach.

Podsumowując, jeśli nie masz wielu zasobów do zarządzania, zawsze zalecałbym muteks zamiast semafora.


1
Odpowiedź Feabhasa jest dość ważna - muteks sprawdza wątek, który próbuje zwolnić muteks, w rzeczywistości jest jego właścicielem. Miałem to jako pytanie do wywiadu, więc warto spróbować je zapamiętać.
pasztet

40

Mutex to w zasadzie wzajemne wykluczenie. Tylko jeden wątek może uzyskać zasób na raz. Gdy jeden wątek pozyskuje zasób, żaden inny wątek nie może uzyskać zasobu, dopóki wątek będący właścicielem zasobu nie zostanie zwolniony. Wszystkie wątki oczekujące na pozyskanie zasobu zostałyby zablokowane.

Semafor służy do kontrolowania liczby wykonywanych wątków. Będzie ustalony zestaw zasobów. Liczba zasobów zostanie zmniejszona za każdym razem, gdy wątek jest właścicielem tego samego. Gdy liczba semaforów osiągnie 0, żadne inne wątki nie mogą uzyskać zasobu. Wątki są blokowane do czasu, gdy inne wątki są właścicielami wydania zasobów.

Krótko mówiąc, główna różnica polega na tym, ile wątków może jednocześnie uzyskać zasób?

  • Muteks - to JEDEN.
  • Semafor - jego DEFINED_COUNT, (tyle, ile liczba semaforów)

8

Mutex służy do szeregowego dostępu do zasobu, podczas gdy semafor ogranicza dostęp do zasobu do określonej liczby. Możesz myśleć o muteksie jak o semaforze z liczbą dostępu równą 1. Niezależnie od ustawienia licznika semaforów, wątki mogą uzyskać dostęp do zasobu, zanim zasób zostanie zablokowany.



3

Muteks jest często nazywany semaforem binarnym. Podczas gdy semafor można utworzyć z dowolną liczbą niezerową, muteks jest koncepcyjnie semaforem z górną liczbą 1.



1

Semafor :

Semafor liczący. Koncepcyjnie semafor zachowuje zestaw zezwoleń. Każdy acquire()blokuje się, jeśli to konieczne, aż do uzyskania zezwolenia, a następnie je przyjmuje. Każdy release()dodaje zezwolenie, potencjalnie zwalniając blokującego nabywcę. Jednak żadne rzeczywiste obiekty zezwoleń nie są używane; Semafor po prostu liczy dostępną liczbę i działa odpowiednio.

Semafory są często używane w celu ograniczenia liczby wątków, które mogą uzyskać dostęp do niektórych (fizycznych lub logicznych) zasobów

Java nie ma wbudowanego interfejsu API Mutex. Ale można go zaimplementować jako semafor binarny.

Semafor zainicjowany na jeden semafor, który jest używany w taki sposób, że ma co najwyżej jedno dostępne zezwolenie, może służyć jako blokada wzajemnego wykluczania. Jest to bardziej powszechnie znane jako semafor binarny, ponieważ ma tylko dwa stany: jedno dostępne zezwolenie lub zero dostępnych zezwoleń.

Użyty w ten sposób semafor binarny ma tę właściwość (w przeciwieństwie do wielu implementacji Lock), że "blokada" może zostać zwolniona przez wątek inny niż właściciel (ponieważ semafory nie mają pojęcia własności) . Może to być przydatne w niektórych specjalistycznych kontekstach, takich jak odzyskiwanie zakleszczenia.

A więc kluczowe różnice między Semaphore i Mutex:

  1. Semafor ogranicza liczbę wątków, aby uzyskać dostęp do zasobu za pośrednictwem zezwoleń. Mutex pozwala tylko jednemu wątkowi na dostęp do zasobów.

  2. Żaden wątek nie jest właścicielem Semaphore. Wątki mogą aktualizować liczbę zezwoleń przez wywołanie acquire()i release()metody. Muteksy należy odblokowywać tylko za pomocą nici przytrzymującej zamek.

  3. Kiedy mutex jest używany ze zmiennymi warunkowymi, istnieje domniemany nawias - jest jasne, która część programu jest chroniona . Niekoniecznie tak jest w przypadku semafora, który można by nazwać przejściem do programowania współbieżnego - jest potężny, ale zbyt łatwy w użyciu w nieustrukturyzowany, nieokreślony sposób.


0

Mutex to semafor binarny. Musi być zainicjowany wartością 1, aby spełniona była zasada „kto pierwszy, ten lepszy”. To prowadzi nas do innego specjalnego własności każdego mutex: kto nie w dół , musi być tym, który robi się . W efekcie uzyskaliśmy wzajemne wykluczenie jakiegoś zasobu.

Teraz możesz zobaczyć, że mutex jest specjalnym przypadkiem semafora ogólnego.


0

Przedmiot synchronizacji Semaforrealizuje klasyczną sygnalizację świetlną. Sygnalizacja świetlna kontroluje dostęp do zasobu współdzielonego przez licznik. Jeśli licznik jest większy niż zero, przyznawany jest dostęp; Jeśli wynosi zero, odmowa dostępu. Licznik zlicza uprawnienia, które umożliwiają dostęp do udostępnionego zasobu. Następnie, aby uzyskać dostęp do zasobu, wątek musi otrzymać pozwolenie od sygnalizacji świetlnej. Ogólnie rzecz biorąc, aby użyć sygnalizacji świetlnej, wątek, który chce uzyskać dostęp do udostępnionego zasobu, próbuje uzyskać zezwolenie. Jeśli liczba sygnalizacji świetlnej jest większa od zera, wątek uzyskuje zezwolenie, a liczba sygnalizacji świetlnej jest zmniejszana. W przeciwnym razie wątek zostanie zablokowany do czasu uzyskania pozwolenia. Gdy wątek nie potrzebuje już dostępu do udostępnionego zasobu, zwalnia pozwolenie, więc liczba sygnalizacji świetlnej wzrasta. Jeśli jest inny wątek czekający na zezwolenie, uzyska wtedy zezwolenie. Klasa Semaphore w Javie implementuje ten mechanizm.

Semafor ma dwóch konstruktorów:

Semaphore(int num)
Semaphore(int num, boolean come)

num określa początkową liczbę zezwoleń. Następnie num określa liczbę wątków, które mogą uzyskać dostęp do udostępnionego zasobu w danym momencie. Jeśli num to jeden, może uzyskać dostęp do zasobu po jednym wątku naraz. Przez ustawienie się jak prawdziwy, można zagwarantować, że nici czekasz na pozwolenie są w kolejności ich wniosek.


0

Porównujesz niezrównane, technicznie nie ma różnicy między Semaforem a muteksem, to nie ma sensu. Mutex to po prostu znacząca nazwa, jak każda inna nazwa w logice aplikacji, oznacza to, że inicjalizujesz semafor na "1", jest on używany ogólnie do ochrony zasobu lub chronionej zmiennej w celu zapewnienia wzajemnego wykluczenia.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.