2013-07-16 17 views
23

Próbowałem zrozumieć Reentrant locks i Semaphores (zagnieżdżanie Reentrant locks vs release/unlock mechanism).Binary Semaphore vs ReentrantLock

Wydaje się, że posiadanie semafora wymaga napisania dokładniej przetestowanej aplikacji, ponieważ metoda release() nie sprawdza, czy wątek zwalniający zezwolenie faktycznie go zatrzymuje. Kiedy przetestowałem mój kod testowy, okazało się, że może to następnie zwiększyć liczbę zezwoleń poza początkowy limit. Z drugiej strony, jeśli wątek nie ma blokady ponownego wejścia, gdy wywołuje metodę odblokowania, otrzymujemy wyjątek IllegalMonitorException.

Więc byłoby słuszne stwierdzenie, że nie ma prawdziwego powodu, aby kiedykolwiek mieć binarny semafor, ponieważ wszystko, co może zrobić binarny semafor, może być również wykonane przez ReentrantLock. Gdybyśmy używali semaforów binarnych, musielibyśmy sprawdzić cały stos wywołań metod, aby sprawdzić, czy wcześniej uzyskano zezwolenie (również zostało ono wydane, jeśli istnieje możliwość późniejszego przejęcia - które może zablokować, jeśli zwolnienie nie spowoduje jego wykonania i wkrótce). Również skoro zamki reentrantowe zapewniają również jeden zamek na obiekt, czy nie lepiej jest preferować blokadę reentrantu do semafora binarnego?

Sprawdziłem post tutaj, który mówi o różnicy między binarnym semaforem a muteksem, ale czy istnieje coś takiego jak muteks w Javie?

Dzięki, Chan.

P.S - Wysłałem to pytanie na innym forum (http://www.coderanch.com/t/615796/threads/java/reason-prefer-binary-Semaphore-Reentrant) i nie otrzymałem jeszcze odpowiedzi. Pomyślałem, że też zamieściłem to tutaj, żeby zobaczyć, co mogę dostać.

+0

http://stackoverflow.com/questions/12641933/difference-between-semaphore-and-condition-reentrantlock może pomóc –

+2

To zachowanie jest zgodne z projektem i [dobrze udokumentowane] (http://docs.oracle.com/ javase/7/docs/api/java/util/concurrent/Semaphore.html # release% 28% 29): "* Nie ma wymogu, aby wątek zwalniający zezwolenie musiał uzyskać to zezwolenie, wywołując metodę acquire(). użycie semafora jest ustalane przez programowanie konwencji w aplikacji. * ". Podczas korzystania z ReentrantLocks, musisz upewnić się, że poprawnie zwolniłeś blokadę w bloku finally. To też nie jest egzekwowane, ale jest również dobrze udokumentowane. – assylias

+1

Zobacz też: http://stackoverflow.com/questions/7554839/how-and-why-can-a-semaphore-give-out-more-permits-than-it-was-initialized-with – assylias

Odpowiedz

25

nie ma prawdziwy powód zawsze mieć binarną semafora jak wszystko że binarny semafor może zrobić można również dokonać przez ReentrantLock

Jeśli wszystko czego potrzebujesz to reentrant wzajemnego wykluczania, to tak , nie ma powodu, aby używać semafora binarnego na ReentrantLock. Jeśli z jakiegokolwiek powodu potrzebujesz semantyki o braku własności, wtedy oczywiście semafor jest twoim jedynym wyborem.

Ponadto, ponieważ zamki reentrant zapewniają również jedną blokadę za obiekt, nie jest to zawsze lepszy pomysł, aby preferować blokadę wielowejściowy do semafora binarnego?

To zależy od potrzeb. Jak wcześniej wyjaśniono, jeśli potrzebujesz prostego muteksu, nie wybieraj semafora. Jeśli więcej niż jeden wątek (ale ograniczona liczba) może wejść do sekcji krytycznej, możesz to zrobić poprzez zamknięcie wątku lub semafor.

Sprawdziłem post tutaj mówi o różnicy między semafora binarnego i mutex, ale jest tam coś jak mutex w Java?

ReentrantLock i synchronized są przykładami muteksy w Javie.

+1

Dzięki, John. To było szybkie i pomocne. – Chan

3

Nie będę tłumaczył blokad ponownego wejścia, ponieważ John podał już dobre wyjaśnienie powyżej i jest przykładem muteksa w języku Java wraz ze słowem kluczowym Zsynchronizowane.

Jednakże, jeśli z jakiegokolwiek powodu chciałbyś mieć lepszą kontrolę nad mechanizmem blokującym, Semafor może się przydać.Oznacza to, że twój kod będzie musiał pozostać odpowiedzialny za to, kto nazywa acqu() i kto nazwał release(), ponieważ Semaphore z natury jest ślepy na to, wszystko, na czym to zależy, staje się dostępne.

Innym podejściem do własnej implementacji mutex przy użyciu java jest LockSupport. Działa to trochę jak Semafor, ale ma limit czasu na zezwoleniu, używając funkcji park() i obsługuje tylko jedno zezwolenie w danym czasie, w przeciwieństwie do semaforów, które obsługują wiele z nich.