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

Синхронизированный блок в Java

Блок synchronized (obj) {... } берет монитор указанного объекта только на время фигурных скобок. Так можно защитить одно поле, не блокируя весь метод целиком.

Часто заводят отдельное поле private final Object lock = new Object();, чтобы внешний код не мог случайно синхронизироваться на this и обойти ваши правила.

Приращение только внутри блока:

class Counter { private final Object gate = new Object(); private int total = 0; void addOne() { synchronized (gate) { total++; } } int read() { synchronized (gate) { return total; } } }

Между итерациями можно делать работу без монитора, а блок держать коротким:

public class Main { public static void main(String[] args) throws InterruptedException { Counter counter = new Counter(); Runnable work = () -> { for (int i = 0; i < 500; i++) { try { Thread.sleep(1); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return; } counter.addOne(); } }; Thread a = new Thread(work); Thread b = new Thread(work); a.start(); b.start(); a.join(); b.join(); System.out.println(counter.read()); } }

Монитор gate один на все потоки, которые меняют total. Чтение тоже идет под тем же замком, чтобы не увидеть частично обновленное значение.

Поле visits и объект gate. Три потока после короткой паузы увеличивают счетчик только в synchronized (gate). Итог после join равен 3.

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