Кожного разу, коли виникає запитання щодо синхронізації Java, деякі люди дуже хочуть зазначити, чого synchronized(this)
слід уникати. Натомість, вони стверджують, слід віддати перевагу замок на приватній довідці.
Деякі з наведених причин:
- якийсь злий код може вкрасти ваш замок (дуже популярний цей, також є варіант "випадково")
- всі синхронізовані методи в межах одного класу використовують той самий замок, що зменшує пропускну здатність
- ви (зайво) виставляєте занадто багато інформації
Інші люди, включаючи мене, стверджують, що synchronized(this)
це ідіома, яка багато використовується (також у бібліотеках Java), є безпечною і добре зрозумілою. Цього не слід уникати, оскільки у вас є помилка, і ви не маєте поняття, що відбувається у вашій багатопотоковій програмі. Іншими словами: якщо це застосовно, то використовуйте його.
Мені цікаво побачити приклади реального світу (без речей Foobar), де this
краще уникати блокування , коли synchronized(this)
також робити цю роботу.
Тому: чи слід завжди уникати synchronized(this)
та замінювати його замком на приватній довідці?
Деякі додаткові відомості (оновлені у вигляді відповідей):
- ми говоримо про синхронізацію екземплярів
- розглядаються як неявні (
synchronized
методи), так і явні формиsynchronized(this)
- якщо ви цитуєте Bloch чи інші повноваження з цього приводу, не залишайте частин, які вам не подобаються (наприклад, Ефективна Java, пункт про безпеку теми: Зазвичай це блокування самого екземпляра, але є винятки.)
- якщо вам потрібна деталізація у вашому блокуванні, окрім
synchronized(this)
передбачених, тоsynchronized(this)
це не застосовується, тому це не проблема