Подтвердить что ты не робот

Использование ThreadLocal в корпоративном приложении

Если мое веб-приложение и приложение ejb находятся на одном компьютере (на одном JVM), и все вызовы ejb являются локальными вызовами, будет ли использование ThreadLocal создавать какую-либо проблему при передаче информации из Интернета в ejb?

Любое обходное решение, если вызовы ejb удалены? Будет ли доступна информация о ThreadLocal из веб-приложения в приложение ejb? Возможно ли использование ThreadLocal в таком сценарии?

4b9b3361

Ответ 1

Для первого вопроса нет проблем, если вы удаляете переменные ThreadLocal в конце каждого вызова. Это важно, потому что контейнеры (сервлет или ejb) обычно используют потоки пользователей и, следовательно, повторно используют потоки, это имеет два эффекта: один "вызов" может видеть информацию о потоковом доступе, поступающую от предыдущего вызова, и если вы удалите приложение из контейнера, не останавливая JVM некоторые классы не могут быть собраны в мусор, потому что они по-прежнему ссылаются на поток контейнера. Поэтому поместите данные в threadlocal в блок try/finally и удалите в конечном итоге.

Вот сообщение, показывающее один из способов решения проблемы: ThreadLocal в веб-приложениях

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

Ответ 2

ThreadLocal не следует использовать в контекстах EJB. Нельзя гарантировать, что вызовы метода EJB находятся в одном и том же потоке (конечно, должно быть).

В EJB существует другой подход к вызову TransactionSyncrhonizationRegistry. Подробнее см. Объяснение/Использование.

Ответ 3

все вызовы ejb являются локальными вызовами, будет использоваться ThreadLocal create любой вопрос, пока

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

Любое обходное решение, если вызовы ejb удалены?

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

Ответ 4

При использовании EJB 3.1 вы можете передавать контекстуальную информацию в EJBContext с помощью контекстные данные. Это всего лишь Map<String,Object>.

Ответ 5

Это зависит от того, какую информацию вы передаете! Первый вопрос - слишком общий. Я предлагаю прочитать JavaDoc, связанный с ThreadLocal здесь.

ThreadLocal живет с серверной стороны приложения и используется, чтобы позволить Thread-safe вызовы объектов Thread.

Ответ 6

Для локальных вызовов ThreadLocal должен работать нормально, если все сделано в одном потоке.

Для удаленных вызовов, которые могут запускаться на другом сервере, вам нужно будет придумать что-то еще. Либо передайте все значения в качестве параметров (которые будут работать, но вводят сложность в коде), либо используют что-то вроде распределенного кеша, например. Hazelcast, который будет функционировать как глобальный HashMap, к которому имеют доступ все узлы кластера.

Ответ 7

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

ctx.getContextData() не работает для меня, он всегда возвращает null!

Я также пробовал TransactionSynchronizationRegistry, но я также получил null.

Единственное, что сработало, - это использование JAAS в качестве обходного пути. Но это нехорошее решение.