Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗jvSpSyInr 197 of 322 menu
◀ ▶

Введение в синхронизацию в Java

Два потока могут одновременно читать и менять одно поле объекта. Каждый шаг "прочитать, прибавить, записать" в исходнике выглядит цельным, но JVM между инструкциями переключает потоки, и часть приращений теряется.

Состояние гонки чаще всего замечают на общем счетчике: каждый поток много раз увеличивает переменную, а после join сумма ниже ожидаемой. Проблема не в арифметике, а в том, что операции накладываются во времени.

Синхронизация ограничивает доступ к критическому участку: в один момент его меняет только один поток. В Java для этого есть ключевое слово synchronized, интерфейс Lock и классы из java.util.concurrent.

Проверка на двух потоках по тысяче приращений без защиты обычно дает число ниже 2000:

public class Main { private static int hits = 0; public static void main(String[] args) throws InterruptedException { Runnable step = () -> { for (int i = 0; i < 1000; i++) { hits++; } }; Thread left = new Thread(step, "left"); Thread right = new Thread(step, "right"); left.start(); right.start(); left.join(); right.join(); System.out.println(hits); } }

Запускайте пример несколько раз: итог плавает, хотя логика простая. В следующих уроках закроем участок монитором, явным замком и атомарными типами.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить