Что означает однопоточность сеанса JMS?

Какова точная природа небезопасности потоков сеанса JMS и связанных с ним конструкций (сообщение, потребитель, производитель и т. д.)? Просто доступ к ним должен быть сериализован, или доступ ограничен только создающим потоком?

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

Но рассмотрим "Серверная сторона " пример кода из документации ActiveMQ.

Класс Server имеет элементы данных с именами session (типа Session) и replyProducer (типа MessageProducer), которые

  • создается в одном потоке: в зависимости от того, какой из них вызывает конструктор Server() и тем самым вызывает метод setupMessageQueueConsumer() с фактическими вызовами создания; и
  • используется в другом потоке: в зависимости от того, какой из них вызывает асинхронный обратный вызов onMessage().

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

Этот официальный пример кода работает случайно или по замыслу? Реально ли создать такие объекты в одном потоке, а затем организовать их использование другим потоком?

(Примечание: в других инфраструктурах обмена сообщениями, таких как Solace, можно указать поток, в котором происходят обратные вызовы, что может быть использовано для обхода этого ограничения «сродства потоков объектов», но такой вызов API не определен в JMS, поскольку насколько я знаю.)


person arayq2    schedule 15.07.2015    source источник


Ответы (2)


Спецификация JMS говорит, что объект сеанса не должен использоваться между потоками, кроме как при вызове метода Session.Close(). С технической точки зрения, если доступ к объекту Session или его дочерним элементам (производителю, потребителю и т. д.) сериализован, то доступ к Session или его дочерним объектам можно получить через потоки. При этом, поскольку JMS является спецификацией API, ее реализация отличается от поставщика к поставщику. Некоторые поставщики могут строго обеспечивать соответствие потоков, а некоторые нет. Поэтому всегда лучше придерживаться спецификации JMS и соответственно писать код.

person Shashi    schedule 17.07.2015
comment
Итак, пример кода из документации ActiveMQ работает случайно или по замыслу? Другими словами, соответствует ли он спецификации JMS или нет? - person arayq2; 17.07.2015
comment
На мой взгляд, это не соответствует спецификации. - person Shashi; 19.07.2015

Официальный ответ выглядит как сноска к разделу 4.4. "Сеанс" на стр. 60 в JMS 1.1 спецификация.

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

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

person arayq2    schedule 17.07.2015