Используя Сессию JMS от различных потоков

От javadoc для Сессии это указывает:

Объект Сессии является однопоточным контекстом для создания и потребления сообщений.

Таким образом, я понимаю, что Вы не должны использовать объект Сессии от двух различных потоков одновременно. То, на чем я неясен, - то, если Вы могли бы использовать объект Сессии (или дети, такие как Очередь) от другого потока, чем тот, это создало.

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

Действительно ли это является кошерным?

(Используя ActiveMQ BTW, если это влияет на ответ вообще.)

13
задан Evan 22 March 2010 в 08:05
поделиться

2 ответа

Я думаю, что сноска из раздела 4.4 в спецификации JMS 1.1 проливает свет:

Нет никаких ограничений на количество потоков, которые могут использовать объект Session или те, которые он создает. Ограничение состоит в том, что ресурсы сессии не должны использоваться одновременно несколькими потоками. Пользователь должен убедиться, что это ограничение параллельности соблюдается. Самый простой способ сделать это - использовать один поток. В случае асинхронной доставки используйте один поток для настройки в остановленном режиме, а затем запустите асинхронную доставку. В более сложных случаях пользователь должен обеспечить явную синхронизацию.

Согласно моему прочтению спецификации, то, что вы хотите сделать, нормально, если вы правильно управляете параллелизмом.

11
ответ дан 1 December 2019 в 22:22
поделиться

К сожалению, документация по JMS часто написана не так четко и ясно, как хотелось бы :o(

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

Как только соединение было запущено, любой сеанс с зарегистрированным сообщением слушателем(ями) посвящается потоку управления, который доставляет сообщения ей. Ошибочно для клиентского кода использовать этот сеанс или любой из его составляющих его объектов из другого потока управления. Единственным исключением для этого является использование сеанса или метод закрытия соединения.

Обратите внимание на четкое использование "потока управления" и выделение 'close()' в качестве единственного исключения.

Похоже, они хотят сказать, что даже если вы используете асинхронное потребление сообщений (т.е. setMessageListener) - что означает, что вас вызывают обратно в другой поток, созданный JMS для получения сообщений - вам никогда не разрешается трогать сессию или связанные объекты снова из любого другого потока, потому что сессия теперь "выделена" потоку доставки JMS. Например, я предполагаю, что это означает, что вы не можете даже вызвать message.acknowledge() из другого потока.

Сказав это, я только сейчас заметил, что мы не соблюдаем это ограничение, и пока не заметили никаких плохих последствий (используя SonicMQ). Но, конечно, если вы не подчиняетесь стандарту, все ставки сделаны, так что я полагаю, нам нужно подчиняться правилу 1-потока 1-сессии, чтобы оставаться в безопасности.

11
ответ дан 1 December 2019 в 22:22
поделиться
Другие вопросы по тегам:

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