Использование сеанса JMS из разных потоков - PullRequest
13 голосов
/ 22 марта 2010

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

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

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

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

Это кошерный?

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

Ответы [ 2 ]

11 голосов
/ 08 июня 2010

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

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

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

11 голосов
/ 08 июня 2010

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

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

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

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

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

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

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