Назад к вопросам
Middle
129
questionbank

Назовите различия между synchronized и ReentrantLock?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

  • synchronized — ключевое слово языка. ReentrantLock — класс из пакета java.util.concurrent.locks.
  • synchronized может использоваться для блокировки методов или блоков кода. ReentrantLock блокирует только блоки кода через методы lock() и unlock().
  • synchronized является примитивной формой блокировки, не имеет возможностей тонкой настройки. ReentrantLock предоставляет больше гибкости:
    • Возможность прерывания блокированного потока (lockInterruptibly()).
    • Попытка неблокирующей блокировки (tryLock()).
    • Возможность установить таймаут для попытки блокировки (tryLock(long timeout, TimeUnit unit)).
    • Возможность создать несколько условий ожидания (newCondition()).
  • synchronized автоматически освобождает блокировку при выходе из блокированного блока кода (в том числе при исключениях). ReentrantLock требует явного вызова unlock() в блоке finally, чтобы избежать взаимоблокировки.
  • Производительность ReentrantLock может быть выше при высокой конкуренции потоков по сравнению с synchronized (хотя в последних версиях Java различия могут быть незначительными).
  • ReentrantLock поддерживает честный режим (fairness), при котором потоки получают блокировку в порядке запроса. synchronized не гарантирует честный режим.

Пример использования ReentrantLock:

import java.util.concurrent.locks.ReentrantLock;

public class SharedResource {

    private final ReentrantLock lock = new ReentrantLock();
    private int counter = 0;

    public void increment() {
        lock.lock(); // Получаем блокировку
        try {
            counter++;
            System.out.println(Thread.currentThread().getName() + " incremented counter to " + counter);
        } finally {
            lock.unlock(); // Освобождаем блокировку в блоке finally
        }
    }

    public int getCounter() {
        return counter; // Чтение без блокировки (если не требуется синхронизация чтения)
    }
}

Пример использования synchronized:

public class SharedResourceSynchronized {

    private int counter = 0;

    public synchronized void increment() { // Блокировка на методе
        counter++;
        System.out.println(Thread.currentThread().getName() + " incremented counter to " + counter);
    }

    public int getCounter() {
        return counter;
    }
}