Czy istnieje obiekt Mutex w Javie lub sposób na jego utworzenie? Pytam, ponieważ obiekt Semaphore zainicjowany z 1 zezwoleniem mi nie pomaga. Pomyśl o tym przypadku:
try {
semaphore.acquire();
//do stuff
semaphore.release();
} catch (Exception e) {
semaphore.release();
}
jeśli wyjątek wystąpi przy pierwszym pobraniu, zwolnienie w bloku catch zwiększy zezwolenia, a semafor nie jest już semaforem binarnym.
Czy będzie właściwy sposób?
try {
semaphore.acquire();
//do stuff
} catch (Exception e) {
//exception stuff
} finally {
semaphore.release();
}
Czy powyższy kod zapewni, że semafor będzie binarny?
Odpowiedzi:
Zobacz tę stronę: http://www.oracle.com/technetwork/articles/javase/index-140767.html
Ma nieco inny wzór, który jest (chyba) tym, czego szukasz:
W tym przypadku dzwonisz tylko
release()
po pomyślnym zakończeniuacquire()
źródło
Każdy obiekt w Javie może być używany jako blokada za pomocą
synchronized
bloku. Spowoduje to również automatyczne zwolnienie blokady, gdy wystąpi wyjątek.Możesz przeczytać więcej na ten temat tutaj: Wewnętrzne blokady i synchronizacja
źródło
synchronized
zobaczysz, co jest lepiej czytelne i mniej podatne na błędy.transaction.begin(); transaction.commit()
.).someObject.wait(timeout)
isomeObject.notify()
podczas przeglądania kodu tej odpowiedzi.źródło
"Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements."
from: docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/… ... chociaż masz rację . Odpowiedź Argv nie ilustruje ani nie wyjaśnia tych operacji.private final ReentrantLock _mutex = ...
, możesz użyć metody getHoldCount (), aby zwrócić liczbę ponownych blokad wątków. (Możesz zastosować a,Condition
aby temu zapobiec. Zobacz interfejs API ).Nikt o tym wyraźnie nie wspomniał, ale ten typ wzoru zwykle nie jest odpowiedni dla semaforów. Powodem jest to, że każdy wątek może zwolnić semafor, ale zwykle potrzebujesz tylko wątku właściciela który był pierwotnie zablokowany, mógł odblokować . W tym przypadku w Javie zwykle używamy ReentrantLocks, które można utworzyć w następujący sposób:
A typowy wzór użytkowania to:
Oto przykład w kodzie źródłowym Java, w którym można zobaczyć ten wzorzec w akcji.
Dodatkową zaletą blokad reentrantowych jest wspieranie uczciwości.
Używaj semaforów tylko wtedy, gdy potrzebujesz semantyki zwalniania prawa własności.
źródło
count=1
nie jest blokadą wzajemnego wykluczania.lock
np ? Nie jestem pewien, dlaczego i jestem traktowany jako ta sama istota. może zostać uwolniony przez dowolny wątek, więc może to nie gwarantować ochrony . jakieś pomysły?ReentrantLock
mutex
mutex
binary semaphore
Semaphore
critical section
Myślę, że powinieneś spróbować:
Podczas inicjalizacji semafora:
I w twoim
Runnable Implementation
źródło
Błędem w oryginalnym poście jest wywołanie acquiringu () ustawione wewnątrz pętli try. Oto poprawne podejście do używania semafora „binarnego” (Mutex):
źródło
Aby upewnić się, że a
Semaphore
jest binarny, musisz tylko upewnić się, że podczas tworzenia semafora podano liczbę zezwoleń jako 1. W Javadocs mieć nieco więcej wyjaśnień.źródło
Blokada każdego obiektu różni się nieco od projektu Mutex / Semaphore. Na przykład nie ma sposobu, aby poprawnie zaimplementować przechodzenie przez połączone węzły ze zwolnieniem blokady poprzedniego węzła i przechwyceniem następnego. Ale z muteksem łatwo jest zaimplementować:
Obecnie nie ma takiej klasy w programie
java.util.concurrent
, ale implementację Mutext można znaleźć tutaj Mutex.java . Jeśli chodzi o biblioteki standardowe, Semaphore zapewnia wszystkie te funkcje i wiele więcej.źródło