Многопоточность в Java — зачем нужен synchronized?
Когда несколько потоков работают с одними и теми же данными, могут возникнуть проблемы.
Например:
Если этот метод одновременно вызовут несколько потоков, результат может оказаться меньше ожидаемого.
Причина в том, что counter++ — это не одна операция. Упрощённо это:
1. Прочитать значение counter
2. Увеличить его
3. Записать новое значение
Два потока могут одновременно прочитать одно и то же значение и потерять одно из изменений.
Для защиты критической секции используется synchronized:
Теперь одновременно выполнять этот метод для одного объекта сможет только один поток.
Можно синхронизировать и отдельный блок:
Но важно понимать: synchronized не делает весь код автоматически потокобезопасным. Нужно правильно определить, какие данные являются общими и какая именно операция должна быть защищена.
А если синхронизация нужна только для простого счётчика, часто лучше использовать AtomicInteger:
AtomicInteger counter = new AtomicInteger();
counter.incrementAndGet();
Главная идея: многопоточность — это не только запуск нескольких потоков, но и безопасная работа с общими данными.
Когда несколько потоков работают с одними и теми же данными, могут возникнуть проблемы.
Например:
int counter = 0;
void increment() {
counter++;
}
Если этот метод одновременно вызовут несколько потоков, результат может оказаться меньше ожидаемого.
Причина в том, что counter++ — это не одна операция. Упрощённо это:
1. Прочитать значение counter
2. Увеличить его
3. Записать новое значение
Два потока могут одновременно прочитать одно и то же значение и потерять одно из изменений.
Для защиты критической секции используется synchronized:
synchronized void increment() {
counter++;
}
Теперь одновременно выполнять этот метод для одного объекта сможет только один поток.
Можно синхронизировать и отдельный блок:
synchronized (this) {
counter++;
}
Но важно понимать: synchronized не делает весь код автоматически потокобезопасным. Нужно правильно определить, какие данные являются общими и какая именно операция должна быть защищена.
А если синхронизация нужна только для простого счётчика, часто лучше использовать AtomicInteger:
AtomicInteger counter = new AtomicInteger();
counter.incrementAndGet();
Главная идея: многопоточность — это не только запуск нескольких потоков, но и безопасная работа с общими данными.
Просмотры: 23