Всякий раз, когда возникает вопрос о SO о синхронизации Java, некоторые люди очень хотят указать, что synchronized(this)
следует избегать. Вместо этого они утверждают, что предпочтительнее блокировка частной ссылки.
Некоторые из приведенных причин:
- какой-то злой код может украсть ваш замок (очень популярен этот, также имеет "случайный" вариант)
- все синхронизированные методы в одном классе используют ту же самую блокировку, которая снижает пропускную способность
- вы (излишне) подвергаете слишком много информации
Другие люди, включая меня, утверждают, что synchronized(this)
- это идиома, которая много используется (также в Java-библиотеках), является безопасной и понятной. Его не следует избегать, потому что у вас есть ошибка, и вы не знаете, что происходит в вашей многопоточной программе. Другими словами: если это применимо, используйте его.
Мне интересно увидеть некоторые реальные примеры (без foobar stuff), где избегать блокировки на this
предпочтительнее, когда synchronized(this)
также выполнит задание.
Следовательно: следует ли всегда избегать synchronized(this)
и заменить его на блокировку частной ссылки?
Дополнительная информация (обновляется с учетом ответов):
- мы говорим о синхронизации экземпляров
- рассматриваются как неявные (
synchronized
методы), так и явный видsynchronized(this)
- если вы цитируете Блоха или другие органы по этому вопросу, не оставляйте без внимания те части, которые вам не нравятся (например, "Эффективная Java", пункт "Безопасность потока": обычно это блокировка самого экземпляра, но есть исключения.)
- Если вам нужна гранулярность в вашей блокировке, кроме
synchronized(this)
, тоsynchronized(this)
не применяется, так что не проблема