Мені цікаво, що з них краще на практиці і чому?
Я знайшов, що Lock
і Condition
(та інші новіconcurrent
класи) - це просто більше інструментів для інструментальної групи. Я міг зробити все, що мені потрібно, зі своїм старим молоточком ( synchronized
ключове слово), але це було незручно використовувати в деяких ситуаціях. Деякі з таких незручних ситуацій стали набагато простішими, коли я додав у свій інструментарій більше інструментів: гумовий молоток, молоток з кулькою, стрижень та деякі удари для нігтів. Однак мій старий молоточок з кігтями все ще бачить свою частку використання.
Я не думаю, що один насправді "кращий", ніж інший, але, скоріше, кожен краще підходить для різних проблем. У двох словах, проста модель та орієнтований на сферу застосування synchronized
допомагає захистити мене від помилок у моєму коді, але ті самі переваги іноді є перешкодами у складніших сценаріях. Саме ці складніші сценарії створили паралельний пакет для вирішення проблеми. Але використання цих конструкцій вищого рівня вимагає більш чіткого і ретельного управління кодом.
===
Я думаю, що JavaDoc робить гарну роботу, щоб описати відмінність між Lock
та synchronized
(акцент - мій):
Реалізації блокування забезпечують більш широкі операції блокування, ніж це можна отримати за допомогою синхронізованих методів та операторів. Вони дозволяють більш гнучко структурувати , можуть мати зовсім інші властивості та можуть підтримувати декілька асоційованих об'єктів Condition .
...
Використання синхронізованих методів або операторів забезпечує доступ до замку неявного монітора , пов'язаного з кожним об'єктом, але сили все придбання замку і звільнення відбуваються в блочно-структурованому чином : коли кілька блокувань будуть придбані , вони повинні бути звільнені в порядку зворотної , і всі замки повинні бути випущені в тому ж лексичному обсязі, в якому вони були придбані .
Хоча механізм визначення розміру синхронізованих методів та операторів значно спрощує програмування з блокуваннями монітора та допомагає уникнути багатьох поширених помилок програмування, пов’язаних із блокуваннями, є випадки, коли вам потрібно працювати з блокуваннями більш гнучко. Наприклад, * * деякі алгоритми * для проходження одночасно доступних структур даних вимагають використання "передачі передачі" або "блокування ланцюга" : ви отримуєте блокування вузла A, потім вузол B, потім випускаєте A і отримуєте C, потім відпустіть B і придбайте D тощо. Реалізація інтерфейсу Lock дозволяє використовувати подібні методи, дозволяючи придбати та випустити декілька блокувань у будь-якому порядку . дозволяючи придбати та випустити замок у різних сферах , та
Завдяки цій підвищеній гнучкості виникає додаткова відповідальність . Відсутність блочно-структурована блокування видаляє автоматичний випуск замків , що відбувається з синхронізованими методами і звітністю. У більшості випадків слід використовувати таку ідіому:
...
Коли замикання і відмикання відбувається в різних областях , необхідно дотримуватися обережності , щоб гарантувати , що весь код , який виконується , поки блокування утримується захищена примірочних , нарешті , чи спробувати прилов , щоб гарантувати , що блокування знімається при необхідності.
Реалізації блокування забезпечують додаткову функціональність щодо використання синхронізованих методів та висловлювань, забезпечуючи неблокуючу спробу придбання блокування (tryLock ()), спробу придбати замок, який можна перервати (lockInterruptibly (), та спробу придбати замок, який може закінчитися закінчити час (tryLock (довгий, TimeUnit)).
...