ReentrantLock jest nieuporządkowane , w przeciwieństwie do synchronizedkonstrukcji - to znaczy, że nie trzeba używać strukturę blokową do blokowania, a nawet może posiadać blokadę całej metody. Przykład:
private ReentrantLock lock;
public void foo() {
...
lock.lock();
...
}
public void bar() {
...
lock.unlock();
...
}
Taki przepływ jest niemożliwy do przedstawienia za pomocą jednego monitora w synchronizedkonstrukcji.
Oprócz tego ReentrantLockobsługuje odpytywanie blokady i blokada przerywana czeka na obsługę limitu czasu . ReentrantLockobsługuje także konfigurowalną politykę uczciwości , umożliwiając bardziej elastyczne planowanie wątków.
Konstruktor dla tej klasy akceptuje opcjonalny parametr uczciwości . Po ustawieniu true, w sporze, zamki sprzyjają zapewnieniu dostępu do najdłużej czekającego wątku. W przeciwnym razie ta blokada nie gwarantuje żadnego konkretnego zamówienia dostępu. Programy korzystające z uczciwych blokad, do których dostęp ma wiele wątków, mogą wykazywać niższą ogólną przepustowość (tj. Są wolniejsze; często znacznie wolniejsze) niż programy korzystające z ustawień domyślnych, ale mają mniejsze rozbieżności w czasie w celu uzyskania blokad i zagwarantowania braku głodu. Należy jednak pamiętać, że uczciwość zamków nie gwarantuje rzetelności planowania wątków. Zatem jeden z wielu wątków korzystających z uczciwego zamka może uzyskać go wiele razy z rzędu, podczas gdy inne aktywne wątki nie postępują i obecnie nie utrzymują zamka. Należy również pamiętać, że nieterminowetryLockmetoda nie uwzględnia ustawienia uczciwości. Pomyślnie, jeśli blokada jest dostępna, nawet jeśli czekają inne wątki.
ReentrantLock może być również bardziej skalowalny , działając znacznie lepiej przy większej rywalizacji. Możesz przeczytać więcej na ten temat tutaj .
Twierdzenie to zostało jednak zakwestionowane; zobacz następujący komentarz:
W teście blokady ponownego wysyłania nowa blokada jest tworzona za każdym razem, dlatego nie ma blokady wyłącznej, a dane wynikowe są nieprawidłowe. Ponadto łącze IBM nie oferuje kodu źródłowego dla bazowego testu porównawczego, więc niemożliwe jest określenie, czy test został przeprowadzony poprawnie.
Kiedy należy użyć ReentrantLocks? Zgodnie z tym artykułem developerWorks ...
Odpowiedź jest dość prosta - użyj jej, gdy rzeczywiście potrzebujesz czegoś, co nie zapewnia synchronized, na przykład oczekiwania na czas z blokadą, oczekiwania na blokadę przerywaną, blokady niestrukturalne, wiele zmiennych warunkowych lub odpytywanie blokad. ReentrantLockma również zalety skalowalności i należy go użyć, jeśli rzeczywiście występuje sytuacja, w której występuje duża rywalizacja, ale należy pamiętać, że zdecydowana większość synchronizedbloków prawie nigdy nie wykazuje żadnej rywalizacji, a tym bardziej wysokiej rywalizacji. Radziłbym rozwijać z synchronizacją, dopóki synchronizacja nie okaże się nieodpowiednia, zamiast zakładać, że „wydajność będzie lepsza”, jeśli użyjeszReentrantLock. Pamiętaj, że są to zaawansowane narzędzia dla zaawansowanych użytkowników. (Naprawdę zaawansowani użytkownicy preferują najprostsze narzędzia, jakie mogą znaleźć, dopóki nie przekonają się, że proste narzędzia są nieodpowiednie). Jak zawsze, najpierw popraw to, a potem martw się, czy musisz to zrobić szybciej.