Het sleutelwoord synchronized is in Java geïntroduceerd met de ondersteuning voor multithreading om exclusieve toegang tot codeblokken of methoden vanuit verschillende threads te garanderen. Historisch gezien is dit Java's antwoord op klassieke problemen met race conditions en data-inconsistentie, die ontstaan bij gelijktijdige toegang tot gedeelde gegevens vanuit verschillende threads.
Probleem bij het werken met multithreading — het waarborgen van de "atomariteit" van bewerkingen en het voorkomen van tegenstrijdige wijzigingen van objecttoestanden. Onjuist gebruik van synchronized kan leiden tot deadlocks, prestatieafname of zelfs het ontbreken van synchronisatie bij een onjuiste keuze van monitorobject.
Oplossing — gebruik het sleutelwoord synchronized voor een methode of codeblok waar garantereerd moet worden dat slechts één thread deze sectie tegelijk uitvoert. Kies zorgvuldig het synchronisatieobject, vermijd lange kritische secties, en voor complexere taken gebruik je speciale klassen uit het java.util.concurrent-pakket.
Voorbeeldcode:
public class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } } // Synchronisatie van slechts een deel van de code op een apart object: private final Object lock = new Object(); public void complexIncrement() { synchronized (lock) { // kritieke sectie count++; } }
Belangrijke kenmerken:
Wat is het verschil tussen een gesynchroniseerde methode en een gesynchroniseerd blok?
Een gesynchroniseerde methode blokkeert de "monitor" van het object (of de klasse als de methode static is), een gesynchroniseerd blok maakt het mogelijk een expliciet monitorobject op te geven, wat meer flexibiliteit biedt.
Wat gebeurt er als je verschillende methoden in hetzelfde object synchroniseert?
Als beide methoden als synchronized zijn gemarkeerd (niet static), gebruiken ze beide het object zelf (this) als monitor. Eén thread kan niet in een van de methoden komen terwijl een andere thread erin bezig is.
Kun je static methoden en gewone methoden synchroniseren? Hoe ontgrendelen ze elkaar?
Static methoden gebruiken de monitor van de klasse zelf (het Class-object), gewone methoden gebruiken het exemplaarobject. Daarom blokkeren een statische synchronized-methode en een gewone synchronized-methode elkaar niet.
Een ontwikkelaar synchroniseert methoden van verschillende objecten, maar gebruikt overal dezelfde String als monitor. Dit leidt tot vertraging en "toevallige" deadlocks door hergebruik van strings uit de pool.
Voordelen:
Nadelen:
Synchronisatie op een privé final-object dat alleen binnen de klasse wordt aangemaakt (private final Object lock), en kritieke secties zijn minimaal in tijd.
Voordelen:
Nadelen: