Zastanawiam się czy jest duża różnica w użyciu ReentrantLock
i synchronized (object)
.
Główne różnice to:
Z synchronized
blokowanie/odblokowywanie jest przywiązany do struktury bloku kodu źródłowego. Blokada synchronized
zostanie zwolniona po wyjściu z bloku, niezależnie od tego, jak to zrobisz. Na przykład zostanie zwolniony, jeśli blok zostanie zakończony z powodu nieoczekiwanego wyjątku.
Z wyraźnym blokowaniem tak nie jest, więc można nabyć ReentrantLock
(lub dowolną inną Lock
) w jednej metodzie i zwolnić w innym. Ale druga strona jest taka, że musisz musi pamiętać, aby jawnie zwolnić Lock
we właściwym czasie/miejscu. Jeśli tego nie zrobisz, skończysz z zablokowanym zamkiem i (być może) zakleszczeniem. W skrócie, ReentrantLock
jest bardziej skomplikowany i potencjalnie bardziej podatny na błędy.
Prymitywne blokowanie, które można uzyskać z synchronized
, współpracuje z Object.wait()
i Object.notify()
. Lock
s nie.
A ReentrantLock
może być utworzony jako "uczciwy", co oznacza, że wątki oczekujące na zdobycie danego zamka uzyskają zamek w kolejności 5. Prymitywne zamki są niesprawiedliwe.
Interfejs API ReentrantLock
posiada metody, które można wykorzystać do sprawdzenia, czy blokada jest używana, ustalić długość kolejki blokady, spróbować uzyskać blokadę bez blokowania i różne inne rzeczy. Żadna z tych funkcji nie jest dostępna dla prymitywnych blokad.
Dlaczego nazywa się zamek reentrant? aby zezwolić na wywołanie rekurencyjne z tego samego wątku?
Blokada ponownego wprowadzenia umożliwia wątkowi przytrzymującemu blokadę ponowne jej zdobycie. Jednym ze sposobów, w jaki można to zrobić, jest rekursja, ale są też inne.
Dla rekordów, zamki synchronized
są identyczne, więc nie musisz się martwić o rekursję lub inne scenariusze, w których wątek może uzyskać blokadę, którą już posiada.
@skaffman - To pytanie nie obejmuje tematu "ponownego wprowadzenia". –