ReentrantLock є неструктурованим , в відміну від synchronized
конструкцій - тобто вам не потрібно використовувати блокову структуру для замикання і навіть можете тримати блокування через методу. Приклад:
private ReentrantLock lock;
public void foo() {
...
lock.lock();
...
}
public void bar() {
...
lock.unlock();
...
}
Такий потік неможливо представити за допомогою одного монітора в synchronized
конструкції.
Крім цього, ReentrantLock
підтримує опитування блокування і переривання блокування очікує, що підтримує тайм-аут . ReentrantLock
також має підтримку налаштованої політики справедливості , що дозволяє більш гнучко планувати потоки.
Конструктор цього класу приймає необов'язковий параметр справедливості . Якщо встановлено true
, заперечення, блокування сприяє наданню доступу до потоку, який довго чекає. Інакше цей замок не гарантує конкретного замовлення доступу. Програми з використанням справедливих блокувань, доступ до яких здійснюється у багатьох потоках, можуть відображати меншу загальну пропускну здатність (тобто, повільніше; часто набагато повільніше), ніж ті, що використовують налаштування за замовчуванням, але мають менші відхилення в часі, щоб отримати блокування та гарантувати відсутність голоду. Зауважте, що справедливість замків не гарантує справедливості планування ниток. Таким чином, один з багатьох потоків, що використовують справедливий замок, може отримати його кілька разів поспіль, тоді як інші активні потоки не прогресують і в даний час не тримають замок. Також зауважте, що несвоєчаснеtryLock
метод не шанує встановлення справедливості. Це вдасться, якщо замок доступний, навіть якщо інші потоки чекають.
ReentrantLock
може також бути більш масштабованим , виконуючи набагато кращі результати за вищої конкуренції. Більше про це можна прочитати тут .
Однак ця вимога оспорюється; дивіться наступний коментар:
У тесті блокування повторного замовлення кожен раз створюється новий замок, тому не існує виключного блокування та отримані дані є недійсними. Крім того, посилання IBM не пропонує вихідного коду для базового еталону, тому неможливо визначити, чи тест був проведений правильно.
Коли слід використовувати ReentrantLock
s? Відповідно до цієї статті developerWorks ...
Відповідь досить проста - використовуйте її тоді, коли вам потрібно щось, що вона надає, що synchronized
не, як, наприклад, примикання блокування чекає, переривчастий замок чекає, неблоковані блокування, кілька змінних умов або блокування опитування. ReentrantLock
також має переваги щодо масштабованості, і ви повинні використовувати його, якщо у вас справді виникає ситуація, яка демонструє велику суперечку, але пам’ятайте, що переважна більшість synchronized
блоків навряд чи коли-небудь демонструє суперечки, не кажучи вже про велику суперечку. Я б радив розвиватись із синхронізацією, поки синхронізація не виявиться неадекватною, а не просто припускати, що "продуктивність буде кращою", якщо ви використовуєтеReentrantLock
. Пам'ятайте, це передові інструменти для просунутих користувачів. (І справді просунуті користувачі, як правило, віддають перевагу найпростішим інструментам, які вони можуть знайти, поки не переконаються, що прості інструменти є неадекватними.) Як завжди, спочатку зробіть це правильно, а потім переживайте, чи потрібно вам зробити це швидше.