Использование сеанса JMS из разных потоков

Из javadoc для Session говорится:

Объект Session - это однопоточный контекст для создания и потребления сообщений.

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

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

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

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

Ответы

Ответ 1

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

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

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

Ответ 2

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

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

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

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

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

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