Одна из первых вещей, которые я узнал о разработке Java EE, - это то, что я не должен создавать свои собственные потоки внутри контейнера Java EE. Но когда я думаю об этом, я не знаю причины.
Можете ли вы четко объяснить, почему это не рекомендуется?
Я уверен, что большинству корпоративных приложений нужны какие-то асинхронные задания, такие как почтовые демоны, простаивающие сеансы, задания по очистке и т. Д.
Итак, если действительно не следует создавать потоки, как правильно это делать при необходимости?
java
multithreading
jakarta-ee
LiorH
источник
источник
Ответы:
Это не рекомендуется, потому что все ресурсы в среде предназначены для управления и, возможно, наблюдения за сервером. Кроме того, большая часть контекста, в котором используется поток, обычно прикрепляется к самому потоку выполнения. Если вы просто запустите свой собственный поток (который, я считаю, некоторые серверы даже не разрешат), он не сможет получить доступ к другим ресурсам. Это означает, что вы не можете получить InitialContext и выполнять поиск JNDI для доступа к другим системным ресурсам, таким как фабрики соединений JMS и источники данных.
Есть способы сделать это «правильно», но это зависит от используемой платформы.
Commonj WorkManager является общим для WebSphere и WebLogic, а также для других
Больше информации здесь
И тут
Также несколько дублирует это с сегодняшнего утра
ОБНОВЛЕНИЕ: обратите внимание, что этот вопрос и ответ относятся к состоянию Java EE в 2009 году, с тех пор ситуация улучшилась!
источник
Для EJB это не только не рекомендуется, но и прямо запрещено спецификацией :
и
Причина в том, что EJB предназначены для работы в распределенной среде. EJB может быть перемещен с одной машины в кластере на другую. Потоки (и сокеты, и другие ограниченные возможности) являются серьезным препятствием для этой переносимости.
источник
Причина, по которой вы не должны создавать свои собственные потоки, заключается в том, что они не будут управляться контейнером. Контейнер заботится о многих вещах, которые новичку сложно представить. Например, такие вещи, как объединение потоков, кластеризация, восстановление после сбоя, выполняются контейнером. Когда вы начинаете обсуждение, вы можете потерять некоторые из них. Кроме того, контейнер позволяет перезапустить приложение, не затрагивая JVM, на которой оно работает. Как это было бы возможно, если есть потоки, не контролируемые контейнером?
Это причина того, что из J2EE 1.4 были введены службы таймера. Подробнее см. В этой статье.
источник
Утилиты параллелизма для Java EE
Теперь существует стандартный и правильный способ создания потоков с помощью основного API Java EE:
Используя Concurrency Utils, вы гарантируете, что ваш новый поток будет создан и управляется контейнером, что гарантирует доступность всех EE-сервисов.
Примеры здесь
источник
Вы всегда можете указать контейнеру запускать что-то как часть ваших дескрипторов развертывания. Затем они могут выполнять любые задачи по обслуживанию, которые вам нужны.
Следовать правилам. Вы будете рады когда-нибудь, что сделали :)
источник
Согласно чертежам, потоки в контейнерах Java EE запрещены. Пожалуйста, обратитесь к чертежам для получения дополнительной информации.
источник
Нет реальной причины не делать этого. Я без проблем использовал Quarz с Spring в веб-приложении. Также
java.util.concurrent
может использоваться структура параллелизма . Если вы реализуете собственную обработку потоков, установите для theads значение deamon или используйте для них собственную группу потоков deamon, чтобы контейнер мог выгрузить ваше веб-приложение в любое время.Но будьте осторожны, сеанс и запрос областей действия bean-компонентов не работают в порожденных потоках! Также другой код
ThreadLocal
не работает из коробки, вам нужно передать значения порожденным потокам самостоятельно.источник
Я никогда не читал, что это не рекомендуется, за исключением того факта, что это непросто сделать правильно.
Это довольно низкоуровневое программирование, и, как и другие низкоуровневые техники, у вас должна быть веская причина. Большинство проблем параллелизма можно решить гораздо эффективнее, используя встроенные конструкции, такие как пулы потоков.
источник
Я обнаружил одну причину: если вы создаете несколько потоков в своем EJB, а затем пытаетесь выгрузить контейнер или обновить свой EJB, вы столкнетесь с проблемами. Почти всегда есть другой способ сделать что-то, где вам не нужен поток, поэтому просто скажите НЕТ.
источник