Синхронизированные методы медленнее в однопоточных приложениях? - PullRequest
11 голосов
/ 10 июня 2009

Я обсуждал это с собой последние несколько минут, и я вижу причины и для да, и для нет. Это связано с поиском ответов на Java HashMap vs. Hashtable и наблюдением того, как несколько человек говорят, что Hashtable на самом деле медленнее.

Мне кажется, что синхронизированный метод должен действовать абсолютно не иначе, чем его несинхронизированный аналог, если выполняется в одном потоке, поскольку действие синхронизации ничего не должно блокировать. Тем не менее, я думаю, что компилятор обрабатывает два случая по-разному, и поэтому люди говорят, что синхронизируется медленнее.

Не то чтобы это было каким-то образом окончательным, но я провел несколько простых тестов на HashMap против Hashtable и увидел небольшую разницу в скорости.

Ответы [ 3 ]

15 голосов
/ 10 июня 2009

Да, однопоточные Java-программы, использующие синхронизацию , могут быть немного медленнее, чем без синхронизации. Для ранних выпусков Java синхронизация была дорогой. Однако для любого современного выпуска неконтролируемая синхронизация довольно дешева. Я бы не волновался об этом.

Обратите внимание, что в Java 6 и Java 7 предусмотрены хорошие оптимизации блокировки:

  • Укрупнение замка
  • Lock elision
  • Адаптивная блокировка спина
  • Смещенная блокировка

Для получения дополнительной информации см. Технический документ Java SE 6 Performance . Также обратите внимание, что неконтролируемая синхронизация представляется более дорогостоящей на многоядерных процессорах, чем на одноядерных, возможно, из-за требований синхронизации модели памяти Java, заставляющих локальные кэши совместно использовать другие процессоры, или какого-либо другого барьера памяти. Например, прочитайте Работают ли оптимизации потоков в Java 6 на самом деле? - Часть II . (Часть I была не такой проницательной, как Часть II.)

5 голосов
/ 10 июня 2009

Да. Они будут немного медленнее из-за дополнительных затрат на поддержание блокировок.

0 голосов
/ 10 июня 2009

При использовании синхронизированных структур данных замедление не зависит от того, «сколько» блокируется. Процесс получения или снятия блокировки происходит медленно, поскольку обычно включает в себя что-то вроде системного вызова (переключение контекста происходит медленно на любой платформе). В среде JIT, такой как типичная JVM, теоретически было бы возможно оптимизировать все вызовы блокировки / разблокировки, когда запущен только один поток, но это должно быть должным образом аннулировано при запуске другого потока.

Обратите внимание, что такие вещи, как фьютексы Linux, не должны совершать системные вызовы, если нет конфликтов, но их использование все еще медленнее, чем неактивные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...