ProgrammatieBackend ontwikkelaar

Beschrijf hoe de synchronized-blok in Java werkt. Wat zijn de kenmerken, hoe kies je een object voor synchronisatie en hoe kan een verkeerde keuze leiden tot fouten?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

synchronized is een sleutelwoord dat het mogelijk maakt om thread-veilige toegang tot kritieke gedeelten van de code uit te voeren. Het kan worden gebruikt voor een methode (bijv. public synchronized void foo()) of voor een codeblok (synchronized(obj) { ... }). Wanneer een thread de synchronized-blok binnenkomt, verwerft hij de monitor (lock) van het object. Terwijl de monitor bezet is, kunnen andere threads niet binnenkomen in een andere synchronized-blok die hetzelfde object als monitor gebruikt.

Kenmerken:

  • Synchronisatie op hetzelfde object zorgt voor wederzijds uitsluiten (slechts één thread kan de blok tegelijkertijd uitvoeren).
  • Je kunt synchroniseren op this, op een statisch object (bijv. op de klasse), of op een willekeurig object.
  • Als je een object kiest dat toegankelijk is voor meerdere threads of omgekeerd, een te lokaal object, kan je de thread-veiligheid in gevaar brengen.

Voorbeeld van het kiezen van een synchronisatieobject

public class Counter { private int count; private final Object lock = new Object(); // privé object public void increment() { synchronized(lock) { count++; } } }

Waarom is het beter om een privé lock te gebruiken? Omdat als je synchroniseert op een publiek object (bijv. op this of op een publiek string), externe code deze monitor kan veroveren, wat leidt tot deadlocks of incorrecte werking.

Vrag met een val.

Vraag: Wat gebeurt er als je synchroniseert op een object van het type String dat een vast waarde bevat?

Antwoord: Strings in Java zijn geïnternd (dezelfde objecten voor identieke literalen). Als je synchroniseert op een string zoals synchronized("lock"), kun je per ongeluk in conflict komen met andere code die synchroniseert op dezelfde literale, wat leidt tot onverwachte blokkades tussen totaal verschillende delen van het programma.

Voorbeeld (doe dit niet):

synchronized("LOCK") { ... }

Voorbeelden van echte fouten door onwetendheid over de nuances van het onderwerp.


Verhaal

In een multi-threaded handelsysteem werden publieke objecten gebruikt voor synchronisatie, waardoor externe code de lock kon veroveren, wat leidde tot tijdelijke deadlocks tussen threads van verschillende modules en stilstand op de beurs.


Verhaal

Een jonge ontwikkelaar synchroniseerde de toegang tot een collectie op een stringliteral. Een ander deel van de code synchroniseerde ook op een string met dezelfde waarde. Deze threads stonden in de rij achter elkaar, wat leidde tot een aanzienlijke vertraging van de bedrijfslogica.


Verhaal

Er werd elke keer een nieuw object gekozen voor synchronisatie: synchronized(new Object()) { ... }. Als gevolg hiervan werkte de synchronisatie helemaal niet, en hadden verschillende threads gelijktijdig toegang tot de gegevens. Dit werd pas ontdekt tijdens belastingtesten.