2013-05-27 13 views
5

Czy używanie zamków (java.util.concurrent.locks.Lock) zamiast słowa kluczowego synchronized + metoda wait() i metoda notify() są całkowicie takie same?Jawne zamki kontra Implicit Locks

Czy mogę bezpiecznie programować przy użyciu blokad (jawnych blokad) zamiast ukrytych blokad (synchronized)?

Jak wiadomo, zawsze stosowałem implicite locks. Jestem świadomy korzyści wynikających z implementacji interfejsu Lock, takich jak: isLocked(), getLockQueueLength(), getHoldCount(), itp ... jednak nadal oldschool sposób (wait() i notify()) miałby inne ograniczenia oprócz tych metod?

Jestem również świadomy możliwości skonstruowania zamka z parametrem (boolean fairness), który pozwala na brak głodu.

+1

Cóż, nie jest * całkowicie * taki sam, jak gdyby były w 100% identyczne, to istnienie jednego byłoby zbędne ;-) –

+1

@Joachim Sauer Z pewnością nie byłby to pierwszy raz, gdy język programowania miałby dwie identyczne sposoby robienia tego samego. – Patashu

+1

@Patashu: na pewno nie. Ale jest mało prawdopodobne, że dodaliby drugą opcję długo po pierwszej, gdyby nie było przynajmniej niektórych zalet (takich jak metoda 'isLocked()', ...). –

Odpowiedz

7

Tak, absolutnie można napisać program bezpieczny dla wątków za pomocą java.util.concurrent.locks.Lock. Jeśli widzisz implementację java.util.concurrent.locks.Lock, taką jak wewnętrzna implementacja, używa się starych bloków .

Implementacje blokad zapewniają bardziej rozbudowane operacje blokowania, niż można uzyskać za pomocą zsynchronizowanych metod i instrukcji. Pozwalają na bardziej elastyczną strukturę, mogą mieć zupełnie inne właściwości i mogą obsługiwać wiele powiązanych obiektów warunku.

Dodając do mojej różnicy słowo kluczowe synchronized ma naturalnie wbudowaną obsługę języków. Może to oznaczać, że JIT może zoptymalizować synchronised blocks w sposób, w jaki nie może z Locks. na przykład może łączyć synchronized blocks. zsynchronizowany jest najlepszy dla niewielkiej liczby wątków uzyskujących dostęp do blokady, a Lock może być najlepszy dla dużej liczby wątków uzyskujących dostęp do tych samych zamków. Również blok synchronized sprawia, że ​​nie gwarantuje o sekwencji, w której wątkom oczekującym na wejście przyznano dostęp.

2

Blokady i bloki synchronized mają tę samą semantykę i zapewniają takie same gwarancje z perspektywy modelu pamięci Java. Główną różnicą jest to, że zamki zapewniają większą kontrolę (np. Z tryLock lub gdy żądają blokady, aby były uczciwe itp.), Które pozwalają na bardziej elastyczne i drobnoziarniste zarządzanie zamkami.

Jednakże, gdy nie potrzebujesz tych dodatkowych funkcji, lepiej użyć zwykłego starego bloku synchronized, ponieważ zmniejsza to miejsce na błąd (np. Nie możesz "zapomnieć" o tym unlock).