Почему нерестовые потоки в контейнере Java EE обескуражены?

Одна из первых вещей, которые я узнал о разработке Java EE, заключается в том, что я не должен создавать свои собственные потоки внутри контейнера Java EE. Но когда я задумываюсь об этом, я не знаю причины.

Можете ли вы четко объяснить, почему это не рекомендуется?

Я уверен, что большинству корпоративных приложений нужны какие-то асинхронные задания, такие как почтовые демона, сеансы бездействия, рабочие места для очистки и т.д.

Итак, если действительно не нужно создавать нити, каков правильный способ сделать это при необходимости?

Ответ 1

Это обескураживает, потому что все ресурсы в среде предназначены для управления и мониторинга на сервере. Кроме того, большая часть контекста, в котором используется поток, обычно прикрепляется к самому потоку выполнения. Если вы просто запустите свой собственный поток (который, я считаю, некоторые серверы даже не разрешают), он не может получить доступ к другим ресурсам. Это означает, что вы не можете получить InitialContext и искать JNDI для доступа к другим системным ресурсам, таким как JMS Connection Factories и Datasources.

Есть способы сделать это "правильно", но это зависит от используемой платформы.

Commonj WorkManager распространен для WebSphere и WebLogic, а также для других

Больше информации здесь

И здесь

Также несколько дублирует это с сегодняшнего утра

ОБНОВЛЕНИЕ: Обратите внимание, что этот вопрос и ответ относятся к состоянию Java EE в 2009 году, с тех пор ситуация улучшилась!

Ответ 2

Для EJB это не только обескураживает, он явно запрещен спецификацией:

Предприятие bean не должно использовать поток синхронизирующие примитивы синхронизировать выполнение нескольких экземпляры.

и

Предприятие bean не должно пытаться для управления потоками. Предприятие bean не следует пытаться запускать, останавливать, приостановить или возобновить поток, или изменить приоритет или имя потока. Предприятие bean не должно пытаться для управления группами потоков.

Причина в том, что EJB предназначены для работы в распределенной среде. EJB может быть перемещен с одного компьютера в кластере на другой. Нити (и розетки и другие ограниченные объекты) являются значительным препятствием для этой переносимости.

Ответ 3

Причина, по которой вы не должны создавать свои собственные потоки, заключается в том, что контейнер не будет управляться. Контейнер заботится о многих вещах, которые начинающий разработчик может найти трудно себе представить. Например, в контейнере выполняются такие вещи, как объединение потоков, кластеризация, восстановление сбоев. Когда вы начинаете поток, вы можете потерять некоторые из них. Также контейнер позволяет перезапустить приложение, не затрагивая JVM, на котором он работает. Как это было бы возможно, если из управления контейнером есть потоки?

Это объясняется тем, что из услуг таймера J2EE 1.4 были введены. Подробнее см. эту статью.

Ответ 4

Concurrency Утилиты для Java EE

Теперь существует стандартный и правильный способ создания потоков с ядром Java EE API:

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

Примеры здесь

Ответ 5

Нет реальной причины не делать этого. Я использовал Quarz с Spring в webapp без проблем. Также может использоваться инфраструктура concurrency java.util.concurrent. Если вы реализуете собственную обработку потоков, установите theads в deamon или используйте для них собственную группу потоков deamon, чтобы контейнер мог выгрузить ваш webapp любой время.

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

Ответ 6

Вы всегда можете сказать, что контейнер запускает материал как часть дескрипторов развертывания. Затем они могут выполнять любые задачи обслуживания, которые вам нужно выполнить.

Следуйте правилам. Когда-нибудь вы будете рады:)

Ответ 7

В контейнерах Java EE в соответствии с чертежами запрещены потоки. Для получения дополнительной информации см. blueprints.

Ответ 8

Я никогда не читал, что это обескуражило, за исключением того, что это нелегко сделать правильно.

Это довольно низкоуровневое программирование, и, как и другие низкоуровневые методы, вы должны иметь вескую причину. Большинство проблем concurrency можно решить гораздо более эффективно, используя встроенные конструкторы, такие как пулы потоков.

Ответ 9

Одна из причин, по которой я обнаружил, что вы порождаете некоторые потоки в EJB, а затем пытаетесь выгрузить контейнер или обновить свой EJB, вы столкнетесь с проблемами. Существует почти всегда другой способ сделать что-то, где вам не нужен поток, поэтому просто скажите "НЕТ".