2016-04-02 5 views
7

Czy istnieje różnica między "ReentrantLock" i "zsynchronizowany", w jaki sposób jest on implementowany na poziomie procesora? Czy też używają tego samego podejścia "CAS"?ReentrantLock vs zsynchronizowany na poziomie procesora?

+0

Proszę mnie poprawić, jeśli się mylę. Jeśli chodzi o moją wiedzę, wątki java nie są widoczne na poziomie procesora. Te blokady są tylko implementacją uruchamianą w środowisku wykonawczym java. Środowisko wykonawcze Java wykonuje instrukcje w celu upewnienia się, że każdy wątek jest sprawdzany. Blokady są również używane w poziomie JRE. W skrócie, wątki Java dzielą się na wątki na poziomie oprogramowania, a nie na wątki poziomu jądra (jak w oknach). –

+0

W przypadku systemu UNIX nie ma wątków na poziomie jądra. UNIX traktuje wątki i procesy tak samo. Ale w oknach używają wątków poziomu jądra. Tak więc rozumiem, że wątki poziomu jądra nie mają nic wspólnego z wątkami java. –

+4

@ImeshaSudasingha nie, wątki Java są nićmi rodzimymi (na każdej maszynie JVM, którą znam). –

Odpowiedz

1

Klasa ReentrantLock, która implementuje blokadę, ma tę samą współbieżność i semantykę pamięci, co zsynchronizowane, ale także dodaje funkcje, takie jak odpytywanie blokady, oczekiwanie na czasową blokadę i oczekiwania na przerwanie blokady. Dodatkowo oferuje znacznie lepszą wydajność podczas ciężkiej rywalizacji.

Source

powyższa odpowiedź jest ekstrakt z Brian Goetz's article. Powinieneś przeczytać cały artykuł. Pomogło mi zrozumieć różnice w obu.

+3

Sytuacja bardzo się rozwinęła od czasu Java 5. W swojej książce Brian Goetz mówi, że wydajność obu zależy od wersji i nie należy zakładać, że jest szybsza od drugiej. i nie powinieneś dokonywać wyboru w oparciu o obawy dotyczące wydajności. Cytat: * nie jest dobrym pomysłem wybór ReentrantLock zsynchronizowany ze względu na wydajność. * –

+0

@JBNizet jak zadałem pytanie Chciałem powiedzieć, że oba mechanizmy mają tę samą współbieżność i semantykę pamięci. Tak, to ewoluuje, ale to stwierdzenie wciąż jest prawdziwe. – Vipin

8

Jeśli mówimy o ReentrantLock vs synchronized (znany również jako „wewnętrzną blokadą”) to jest to dobry pomysł, aby spojrzeć na Lock documentation: implementacje

Wszystko LOCK musi egzekwować te same semantykę synchronizacji pamięci przewidziane przez wbudowaną blokadą monitora:

  • Udana operacja blokada działa jak udane monitorEnter działanie
  • Udana un Operacja lock działa jak udane monitorExit działania

Więc generalnie uważają, że synchronized jest tylko łatwy w obsłudze i zwięzłe podejście z blokadą. Możesz osiągnąć dokładnie takie same efekty synchronizacji, pisząc kod z ReentrantLock z nieco większym kodem (ale oferuje więcej opcji i elastyczność).

Jakiś czas temu ReentrantLock było sposób szybciej pod pewnymi warunkami (wysoki rywalizacji na przykład), ale teraz Java wykorzystuje różne optymalizacje technik (jak brutalizacji zamkiem i blokadą adaptacyjne), aby różnice wydajności w wielu typowych scenariuszy ledwo widocznych dla programisty.

Wykonano również świetną robotę, aby zoptymalizować blokadę wewnętrzną w przypadkach o niskim poziomie rywalizacji (np. Tendencyjne blokowanie). Autorzy platformy Java lubią podejście oparte na słowach kluczowych i wewnętrznym blokowaniu, chcą, aby programiści nie obawiali się używać tego przydatnego narzędzia (i zapobiegać ewentualnym błędom). Właśnie dlatego synchronized optymalizacje i "synchronizacja jest wolna" mity busting było tak wielką sprawą dla Sun i Oracle.

„CPU-część” z pytaniem: synchronized wykorzystuje mechanizm blokujący, który jest wbudowany w instrukcji JVM i MONITORENTER/MONITOREXIT kodu bajtowego. Tak więc podstawowa implementacja jest specyficzna dla JVM (dlatego nazywa się wewnętrzna blokada) i AFAIK zwykle (podlega zmianie) używa dość konserwatywnej strategii: gdy blokada jest "zawyżona" po kolizji gwintów na przejmowaniu zamka, synchronized zacznij używać blokowania opartego na systemie operacyjnym ("blokowanie tłuszczu") zamiast szybkiego CAS ("cienkie blokowanie") i nie "lubię" używać ponownie CAS (nawet jeśli nie ma rywalizacji).

ReentrantLock realizacja opiera się na AbstractQueuedSynchronizer i kodowane w czystej Javie (używa instrukcji CAS i nici wykreślanie który wprowadził ją Java 5), ​​dzięki czemu jest bardziej stabilna na różnych platformach, oferuje większą elastyczność i próbuje użyć szybki appoach CAS pozyskiwania blokada za każdym razem (i blokowanie na poziomie systemu operacyjnego, jeśli się nie powiodło).

Główną różnicą między tymi implementacjami blokad pod względem wydajności jest strategia blokowania (która może nie istnieć w konkretnej implementacji lub sytuacji JVM).

I nie ma żadnej ogólnej odpowiedzi, która blokada jest lepsza + to może ulec zmianie w czasie i platformach. Należy spojrzeć na konkretnym problemie i jego charakter, aby wybrać najbardziej odpowiednie rozwiązanie (jak zwykle w Javie)

PS: jesteś całkiem ciekawy i bardzo polecam spojrzeć na źródła HotSpot głębiej (i aby znaleźć dokładne implementacje dla konkretnej wersji platformy). To może naprawdę pomóc. Punkt wyjściowy jest gdzieś tutaj: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/runtime/synchronizer.cpp

+0

, ale dlaczego blokada Reentrant jest/była "szybsza", jeśli implementacja jest taka sama? –

+0

ich semantyka jest taka sama dla wielu scenariuszy, ale nie implementacja – Cootri

+0

OK, ale jestem sumienny: jaka jest różnica w implementacji? Dlaczego ReentrantLock jest szybszy? –