Избегать синхронизации (это) в Java? - PullRequest
358 голосов
/ 14 января 2009

Всякий раз, когда в SO возникает вопрос о синхронизации Java, некоторые люди очень хотят указать, что synchronized(this) следует избегать. Вместо этого, они утверждают, что блокировка частной ссылки должна быть предпочтительной.

Некоторые из приведенных причин:

Другие люди, включая меня, утверждают, что synchronized(this) - это идиома, которая часто используется (также в библиотеках Java), безопасна и понятна. Этого не следует избегать, потому что у вас есть ошибка, и вы не знаете, что происходит в вашей многопоточной программе. Другими словами: если это применимо, используйте его.

Мне интересно посмотреть на некоторые примеры из реальной жизни (без использования foobar), где предпочтительнее избегать блокировки на this, когда synchronized(this) также сделает эту работу.

Поэтому: следует ли вам всегда избегать synchronized(this) и заменить его блокировкой на личную ссылку?


Дополнительная информация (обновляется по мере получения ответов):

  • речь идет о синхронизации экземпляров
  • и неявные (synchronized методы), и явная форма synchronized(this) считаются
  • если вы цитируете Блоха или другие авторитеты по этому вопросу, не пропускайте части, которые вам не нравятся (например, «Эффективная Java», пункт «Безопасность потоков»: Обычно это блокировка самого экземпляра, но Есть исключения.)
  • если вам нужна гранулярность в блокировке, отличной от synchronized(this), то synchronized(this) не применима, поэтому проблема не в этом

Ответы [ 21 ]

0 голосов
/ 14 января 2009

Это зависит от задачи, которую вы хотите выполнить, но я бы не стал ее использовать. Кроме того, проверьте, не удалось ли выполнить сохранение потока, которое вы хотите выполнить, с помощью синхронизации (это) в первую очередь? Есть также несколько хороших блокировок в API , которые могут вам помочь:)

...