Za każdym razem, gdy pojawia się pytanie na temat SO dotyczące synchronizacji Java, niektórzy bardzo chętnie wskazują, że synchronized(this)
należy tego unikać. Zamiast tego twierdzą, że preferowana jest blokada prywatnego odwołania.
Niektóre z podanych powodów to:
- jakiś zły kod może ukraść twoją blokadę (bardzo popularny ten, ma również wariant „przypadkowo”)
- wszystkie zsynchronizowane metody w tej samej klasie używają dokładnie tej samej blokady, co zmniejsza przepustowość
- (niepotrzebnie) ujawniasz zbyt wiele informacji
Inni ludzie, w tym ja, twierdzą, że synchronized(this)
jest to często używany idiom (także w bibliotekach Java), bezpieczny i dobrze rozumiany. Nie należy tego unikać, ponieważ masz błąd i nie masz pojęcia, co dzieje się w twoim programie wielowątkowym. Innymi słowy: jeśli ma to zastosowanie, użyj go.
Chciałbym zobaczyć przykłady z prawdziwego świata (bez fobarów), w których this
lepiej unikać unikania blokady, gdybym synchronized(this)
również wykonał zadanie.
Dlatego: czy zawsze należy go unikać synchronized(this)
i zastępować zamkiem prywatnego odniesienia?
Kilka dodatkowych informacji (zaktualizowanych po udzieleniu odpowiedzi):
- mówimy o synchronizacji instancji
- brane są pod uwagę zarówno domniemane (
synchronized
metody), jak i jawna formasynchronized(this)
- jeśli cytujesz Blocha lub inne autorytety na ten temat, nie pomijaj części, które ci się nie podobają (np. Efektywna Java, element dotyczący bezpieczeństwa wątków: Zazwyczaj jest to blokada samej instancji, ale są wyjątki).
- jeśli potrzebujesz szczegółowości w blokowaniu innym niż
synchronized(this)
zapewnia,synchronized(this)
to nie dotyczy, więc nie o to chodzi