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
, Помните, что это продвинутые инструменты для опытных пользователей. (И действительно продвинутые пользователи, как правило, предпочитают самые простые инструменты, которые они могут найти, пока они не убедятся, что простые инструменты неадекватны.) Как всегда, сначала сделайте все правильно, а потом беспокойтесь о том, нужно ли вам делать это быстрее.