ReentrantLock является неструктурированным , в отличии от synchronizedконструкций - т.е. вам не нужно использовать блочную структуру для запирания и даже можете держать блокировку через методу. Пример:
private ReentrantLock lock;
public void foo() {
...
lock.lock();
...
}
public void bar() {
...
lock.unlock();
...
}
Такой поток невозможно представить с помощью одного монитора в synchronizedконструкции.
Кроме того, ReentrantLockподдерживает блокировку опроса и прерываемые ожидания блокировок , которые поддерживают тайм-аут . ReentrantLockтакже имеется поддержка настраиваемой политики справедливости , что позволяет более гибко планировать потоки.
Конструктор для этого класса принимает необязательный параметр справедливости . Когда установлено true, в условиях конкуренции блокировки блокируют доступ к самому длинному ожидающему потоку. В противном случае эта блокировка не гарантирует какой-либо конкретный порядок доступа. Программы, использующие справедливые блокировки, к которым обращаются многие потоки, могут показывать более низкую общую пропускную способность (т.е. медленнее, часто намного медленнее), чем программы, использующие настройку по умолчанию, но имеют меньшие отклонения во времени для получения блокировок и гарантируют отсутствие голодания. Однако обратите внимание, что справедливость блокировок не гарантирует справедливость планирования потоков. Таким образом, один из множества потоков, использующих надежную блокировку, может получить ее несколько раз подряд, в то время как другие активные потоки не выполняются и в настоящее время не удерживают блокировку. Также обратите внимание на то, чтоtryLockМетод не соблюдает настройки честности. Это будет успешно, если блокировка доступна, даже если другие потоки ожидают.
ReentrantLock также может быть более масштабируемым , выступая намного лучше при более высокой конкуренции. Вы можете прочитать больше об этом здесь .
Это требование было оспорено, однако; см. следующий комментарий:
В тесте на повторную входящую блокировку каждый раз создается новая блокировка, поэтому исключительная блокировка отсутствует, а полученные данные являются недействительными. Кроме того, ссылка IBM не предлагает исходного кода для базового теста, поэтому невозможно определить, был ли тест даже проведен правильно.
Когда вы должны использовать ReentrantLockс? Согласно этой статье developerWorks ...
Ответ довольно прост - используйте его, когда вам на самом деле нужно что-то, что он предоставляет, что synchronizedне имеет, например, таймерных блокировок, прерывистых блокировок, неблокированных структурных блокировок, нескольких переменных условий или опроса блокировок. ReentrantLockтакже имеет преимущества масштабируемости, и вы должны использовать его, если на самом деле вы столкнулись с высокой конкуренцией, но помните, что в подавляющем большинстве synchronizedблоков конкуренция практически отсутствует, не говоря уже о высокой конкуренции. Я бы посоветовал разрабатывать с синхронизацией до тех пор, пока синхронизация не окажется неадекватной, а не просто предполагать, что «производительность будет лучше», если вы используетеReentrantLock, Помните, что это продвинутые инструменты для опытных пользователей. (И действительно продвинутые пользователи, как правило, предпочитают самые простые инструменты, которые они могут найти, пока они не убедятся, что простые инструменты неадекватны.) Как всегда, сначала сделайте все правильно, а потом беспокойтесь о том, нужно ли вам делать это быстрее.