Słowo kluczowe synchronized pojawiło się w Javie od momentu wsparcia wielowątkowości, aby zapewnić wyłączny dostęp do bloków kodu lub metod z różnych wątków. Historycznie to odpowiedź Javy na klasyczne problemy związane z warunkami wyścigu (race condition) i niespójnością danych (data inconsistency), które występują przy jednoczesnym dostępie do wspólnych danych z różnych wątków.
Problem przy pracy z wielowątkowością — zapewnienie "atomowości" operacji i zapobieganie sprzecznym zmianom stanów obiektów. Niewłaściwa praca z synchronized może prowadzić do zakleszczeń (deadlock), degradacji wydajności lub nawet do braku synchronizacji przy niewłaściwym wyborze obiektu monitorującego.
Rozwiązanie — używać słowa kluczowego synchronized dla metody lub bloku kodu, gdzie należy zapewnić, że tylko jeden wątek jednocześnie wykonuje ten fragment. Należy starannie wybierać obiekt synchronizujący, unikać długich sekcji krytycznych, a do bardziej złożonych zadań stosować specjalne klasy z pakietu java.util.concurrent.
Przykład kodu:
public class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } } // Synchronizacja tylko części kodu na oddzielnym obiekcie: private final Object lock = new Object(); public void complexIncrement() { synchronized (lock) { // sekcja krytyczna count++; } }
Kluczowe cechy:
Jakie są różnice między metodą synchronized a blokiem synchronized?
Synchronizowana metoda blokuje "monitor" obiektu (lub klasy, jeśli metoda jest statyczna), synchronizowany blok pozwala jawnie określić obiekt-monitor, co daje większą elastyczność.
Co się stanie, jeśli w jednym obiekcie synchronizować różne metody?
Jeśli obie metody są oznaczone słowem synchronized (nie statyczne), obie używają jako monitora samego obiektu (this). Jeden wątek nie będzie mógł wejść do żadnej z metod, dopóki inny będzie w nich przebywał.
Czy można synchronizować metody statyczne i zwykłe? Jak się odblokowują nawzajem?
Metody statyczne używają monitora samej klasy (obiekt Class), zwykłe — obiekt instancji. W związku z tym statyczna metoda synchronized i zwykła metoda synchronized nie blokują się nawzajem.
Programista synchronizuje metody różnych obiektów, ale wszędzie używa tego samego Stringa jako monitora. W efekcie pojawia się spowolnienie i "przypadkowe" zakleszczenia z powodu ponownego użycia ciągów z puli.
Zalety:
Wady:
Synchronizacja na prywatnym obiekcie final, który jest tworzony tylko wewnątrz klasy (private final Object lock), a sekcje krytyczne są minimalne pod względem czasu.
Zalety:
Wady: