Назад к вопросам
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;
}
}