← Назад к вопросам

Какие виды мониторов знаешь?

1.0 Junior🔥 161 комментариев
#Многопоточность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Виды Мониторов в Java

Мониторы — это механизм синхронизации, обеспечивающий взаимное исключение и видимость памяти при доступе к общим ресурсам из нескольких потоков.

Встроенный монитор (Intrinsic Lock)

Встроенный монитор реализован непосредственно в объекте Java и использует ключевое слово synchronized. Каждый объект имеет ассоциированный монитор.

public class Counter {
    private int count = 0;
    
    // Синхронизированный метод
    public synchronized void increment() {
        count++;
    }
    
    public synchronized int getCount() {
        return count;
    }
}

Можно также синхронизировать блоки кода:

public class Buffer {
    private List<String> items = new ArrayList<>();
    
    public void add(String item) {
        synchronized(this) {
            items.add(item);
        }
    }
}

Синхронизация статических методов использует монитор класса:

public class Logger {
    private static int logCount = 0;
    
    public static synchronized void log(String message) {
        logCount++;
        System.out.println(message);
    }
}

ReentrantLock

ReentrantLock — это явная реализация интерфейса Lock из пакета java.util.concurrent.locks. Она более гибкая, чем встроенный монитор.

import java.util.concurrent.locks.ReentrantLock;

public class BankAccount {
    private double balance = 0;
    private final ReentrantLock lock = new ReentrantLock();
    
    public void deposit(double amount) {
        lock.lock();
        try {
            balance += amount;
        } finally {
            lock.unlock();
        }
    }
    
    public double getBalance() {
        lock.lock();
        try {
            return balance;
        } finally {
            lock.unlock();
        }
    }
}

Преимущества ReentrantLock:

  • Явная разблокировка в finally блоке (безопаснее)
  • Try-lock с таймаутом
  • Справедливая очередь (fair mode)
  • Несколько условных переменных (Condition)
public class Producer {
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();
    private Queue<String> buffer = new LinkedList<>();
    private static final int CAPACITY = 10;
    
    public void produce(String item) throws InterruptedException {
        lock.lock();
        try {
            while (buffer.size() >= CAPACITY) {
                notFull.await();
            }
            buffer.add(item);
            notFull.signalAll();
        } finally {
            lock.unlock();
        }
    }
}

ReadWriteLock

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

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Cache {
    private Map<String, String> data = new HashMap<>();
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    
    public String get(String key) {
        rwLock.readLock().lock();
        try {
            return data.get(key);
        } finally {
            rwLock.readLock().unlock();
        }
    }
    
    public void put(String key, String value) {
        rwLock.writeLock().lock();
        try {
            data.put(key, value);
        } finally {
            rwLock.writeLock().unlock();
        }
    }
}

StampedLock

StampedLock — это оптимистичный замок для лучшей производительности при большом количестве читателей:

import java.util.concurrent.locks.StampedLock;

public class Point {
    private double x, y;
    private final StampedLock lock = new StampedLock();
    
    public double distanceFromOrigin() {
        long stamp = lock.tryOptimisticRead();
        double currentX = x;
        double currentY = y;
        
        if (!lock.validate(stamp)) {
            stamp = lock.readLock();
            try {
                currentX = x;
                currentY = y;
            } finally {
                lock.unlockRead(stamp);
            }
        }
        
        return Math.sqrt(currentX * currentX + currentY * currentY);
    }
}

Сравнение мониторов

ВидСкоростьСправедливостьГибкость
SynchronizedБыстроНет гарантийНизкая
ReentrantLockНормальноКонфигурируетсяВысокая
ReadWriteLockХорошо для читателейНетСредняя
StampedLockОчень быстроНетСложная

Рекомендации

  • Используй synchronized для простых случаев
  • ReentrantLock для сложной синхронизации
  • ReadWriteLock при доминирующем чтении
  • StampedLock при экстремальных требованиях к производительности