Middle
რა განსხვავებები არსებობს synchronized და ReentrantLock შორის?
sobes.tech AI
პასუხი 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;
}
}