Почему делают все Объекты Java имеют, ожидают () и уведомляют (), и это вызывает хит производительности?

Удаление закрывающих тэгов, когда Вы банка являетесь, вероятно, лучшей практикой действительно. Причина этого состоит в том потому что, если у Вас есть какой-либо символ (даже пробел) за пределами?> в php файле это может остановить вещь, такую как заголовки, чтобы прекратить работать, если символ отправляется в браузер, прежде чем заголовок будет установлен.

20
задан peter.murray.rust 30 October 2009 в 09:33
поделиться

4 ответа

Что ж, это означает, что каждый объект должен потенциально иметь связанный с ним монитор. Тот же монитор используется для синхронизированного . Если вы согласны с решением о возможности синхронизации для любого объекта, то wait () и notify () больше не добавляют состояния для каждого объекта. JVM может лениво выделять фактический монитор (я знаю, что .NET это делает), но должно быть некоторое пространство для хранения, чтобы сказать, какой монитор связан с объектом. По общему признанию, возможно, что это очень небольшая сумма (например, 3 байта), которая в любом случае не сэкономит память из-за заполнения остальной части служебных данных объекта - вам нужно будет посмотреть, как каждая отдельная JVM обрабатывает память, чтобы сказать для уверенности.

Обратите внимание, что наличие дополнительных методов не влияет на производительность (кроме очень незначительного из-за очевидного присутствия кода где-то ). Это не похоже на то, что каждый объект или даже каждый тип имеет свою собственную копию кода для wait () и notify () . В зависимости от того, как работают vtables, каждый тип может иметь дополнительную запись vtable для каждого унаследованного метода - но это все равно только для каждого типа, а не для каждого объекта. По сути, это будет потеряно в шуме по сравнению с большей частью хранилища, которое предназначено для самих объектов.

Лично я считаю, что и .NET, и Java сделали ошибку, связав монитор с каждым объектом - я ' d лучше иметь явные объекты синхронизации.

34
ответ дан 29 November 2019 в 23:20
поделиться

Почему они настолько фундаментальны, что каждый объект должен иметь их и есть успех в том, чтобы иметь их (предположительно какое-то состояние хранится в их)?

tl; dr: Это методы безопасности потоков, и они имеют небольшие затраты по сравнению с их стоимостью.

Фундаментальные реалии, которые поддерживают эти методы , таковы:

  1. Java - это всегда многопоточный. Пример: проверьте список потоков, используемых процессом, использующим jconsole или jvisualvm некоторое время.
  2. Корректность важнее, чем «производительность». Когда я оценивал проекты (много лет назад), мне приходилось объяснять, что «получить неправильный ответ очень быстро все еще неверно»

По сути, эти методы предоставляют некоторые из ловушек для управления Мониторы по объектам, используемые при синхронизации. В частности, если у меня есть synchronized (objectWithMonitor) в конкретном методе, я могу использовать objectWithMonitor.wait () для получения этого монитора (например, если мне нужен другой метод для завершения вычисления, прежде чем я смогу продолжить). В этом случае это позволит еще одному заблокированному методу ожидать продолжения работы этого монитора.

С другой стороны, я могу использовать objectWithMonitor.notifyAll () , чтобы потоки, ожидающие монитора, знали, что я скоро откажусь от монитора. Однако они не могут продолжаться, пока я не выйду из синхронизированного блока.

Что касается конкретных примеров (например, длинных списков двойников), где вы можете беспокоиться о снижении производительности или памяти в механизме мониторинга, вот некоторые моменты, которые вам, вероятно, следует рассмотреть:

  1. Во-первых, докажите это. Если вы думаете, что основной механизм Java, такой как многопоточная корректность, оказывает серьезное влияние, велика вероятность, что ваша интуиция ошибочна. Сначала измерьте удар. Если это серьезно, и вы знаете , что вам никогда не понадобится синхронизация на отдельном двойнике, подумайте об использовании вместо него двойников.
  2. Если вы не уверены, что вы, ваш коллега, будете в будущем поддерживать кодировщику (который может быть самим собой через год) и т. д. никогда никогда никогда не понадобится тонкая детализация направленного доступа к вашим данным, есть отличный шанс, что убрав эти мониторы, вы только сделаете код меньше гибкость и удобство обслуживания.

Дальнейшие действия в ответ на вопрос о конкретных объектах монитора в сравнении с конкретными объектами:

Краткий ответ: @JonSkeet: да, удаление мониторов может создать проблемы: это вызовет трение . Хранение этих мониторов в объекте напоминает нам, что это всегда многопоточная система.

Встроенные мониторы объектов не являются сложными, но их легко объяснить; работать предсказуемо; и ясны по своему назначению. synchronized (this) - четкое заявление о намерениях. Если мы заставим начинающих программистов использовать исключительно пакет параллелизма, это приведет к трению. Что в этом пакете? Что такое семафор? Вилка-соединение?

Начинающий программист может использовать мониторы объектов для написания достойного кода контроллера представления модели. synchronized , wait и notifyAll могут использоваться для реализации наивной (в смысле простой, доступной, но, возможно, не передовой производительности) потоковой безопасности. Каноническим примером может быть один из этих двойников (установленный OP), в котором один поток может устанавливать значение, в то время как поток AWT получает значение, чтобы поместить его в JLabel. В этом случае нет веских причин для создания явного дополнительного объекта только для внешнего монитора.

На несколько более высоком уровне сложности эти же методы полезны в качестве метода внешнего мониторинга. В приведенном выше примере я сделал это явно (см. Фрагменты objectWithMonitor выше). Опять же, эти методы действительно удобны для создания относительно простой безопасности потоков.

Если вы хотите быть еще более изощренным, я думаю, вам следует серьезно подумать о чтении Java Concurrency In Practice (если у вас нет уже нет). Блокировки чтения и записи очень эффективны, не добавляя излишней сложности.

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

12
ответ дан 29 November 2019 в 23:20
поделиться

Все объекты в Java имеют связанные с ними мониторы. Примитивы синхронизации полезны практически во всем многопоточном коде, и семантически очень приятно синхронизировать с объектом (объектами), к которому вы обращаетесь, а не с отдельными объектами «Monitor».

Java может выделять мониторы, связанные с объектами по мере необходимости - как это делает .NET - и в любом случае фактические накладные расходы на простое выделение (но не использование) блокировки будут довольно небольшими.

Короче говоря: очень удобно хранить объекты с их битами поддержки безопасности потоков, и влияние на производительность очень незначительное.

2
ответ дан 29 November 2019 в 23:20
поделиться

Эти методы существуют для реализации межпотокового взаимодействия.

Проверьте эту статью по теме .

Правила для этих методов, взятые из этой статьи:

  • wait () приказывает вызывающему потоку отказаться от монитора и перейти в спящий режим, пока поток входит в тот же монитор и вызывает notify ().
  • notify () пробуждает первый поток, который вызвал wait () для того же объекта.
  • notifyAll () пробуждает все потоки, которые вызывали wait () для того же объекта. тот же объект. В поток с наивысшим приоритетом будет запущен первым.

Надеюсь, это поможет ...

1
ответ дан 29 November 2019 в 23:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: