synchronized

Если два потока меняют одну переменную, они затирают друг друга:

count++;   // на самом деле три действия: прочитать → +1 → записать

Два потока могут прочитать одно и то же значение, оба прибавить 1 и записать — одно увеличение потеряется. Защита — synchronized: пускает в блок только один поток за раз.

synchronized (lock) {
    count++;   // теперь безопасно — один поток за раз
}
Копнуть глубже

Состояние гонки (race condition) — когда результат зависит от того, в каком порядке потоки доберутся до общих данных. count++ не атомарен: это read-modify-write (прочитал, изменил, записал), и между этими шагами может вклиниться другой поток. Поэтому без синхронизации счётчик «теряет» увеличения.

synchronized работает на мониторе (замке) объекта: входя в блок, поток захватывает замок, остальные ждут; на выходе — отпускает. Это даёт и взаимное исключение, и видимость изменений другим потокам.

🎤 Закрыл тему, если можешь объяснить:
• что делает `synchronized`;
• что такое гонка данных и почему `count++` не атомарен (если дошёл до 2-го слоя).