Почему не рекомендуется создавать потоки в контейнере Java EE? - PullRequest
116 голосов
/ 10 февраля 2009

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

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

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

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

Ответы [ 9 ]

84 голосов
/ 10 февраля 2009

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

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

Commonj WorkManager является общим для WebSphere и WebLogic, а также для других

Подробнее здесь

А здесь

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

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

33 голосов
/ 11 февраля 2009

Для EJB не только не рекомендуется, но и категорически запрещено спецификацией :

Корпоративный компонент не должен использовать поток примитивы синхронизации к синхронизировать выполнение нескольких экземпляры.

и

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

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

12 голосов
/ 10 февраля 2009

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

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

7 голосов
/ 16 октября 2013

Утилиты параллелизма для Java EE

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

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

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

2 голосов
/ 23 декабря 2010

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

2 голосов
/ 10 февраля 2009

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

Следуйте правилам. Вы будете рады, что когда-нибудь вы сделали :) 1003 *

2 голосов
/ 10 февраля 2009

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

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

1 голос
/ 11 февраля 2009

Я нашел одну причину, если вы порождаете несколько потоков в вашем EJB, а затем пытаетесь выгрузить контейнер или обновить свой EJB, у вас возникнут проблемы. Почти всегда есть другой способ сделать что-то, где вам не нужен поток, поэтому просто скажите НЕТ.

1 голос
/ 10 февраля 2009

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

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

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