`
gdfloyd
  • 浏览: 74106 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

JMS Session和线程简析

阅读更多

JMS Session和线程简析

JMS API打交道主要是Session对象. HibernateSession设计思路一样, JMS Session是为单线程运行在单线程之下. 有了这点认识, 在并发控制线程同步方面就游刃有余得多了. 查阅官方文档, 总结如下, 下文主要翻译自JavaTM Message Service Specification V1.1

 

l         Session的创建

1. Session是单线程的上下文, Thread Safe.

2. 通过JMS Connection来创建, 相对于Connection来说, 被视为轻量级对象, 换言之, 运行时创建亦无碍.

3. 典型的JMS Client会创建一个Connection, 一个或者若干个Sessions, 若干个消息Producer,Consumer. Hibernate, Session是封装了一个Connection的对象. 而在JMS, 一个Connection往往包含若干个Session.

 

l         Session的关闭

1. Sessions invoke close之时, 若有Message Listener正在running, close并不会立即返回, 而是阻塞等待完成.

2. Sessions invoke close之时, 若有receivepending, close可能导致receive返回null.

3. Sessions关闭后无需对其相关资源进行手动关闭.

4. Sessions invoke close之时, 将导致Transaction rollback.

5. 一旦Sessionsclose, 使用Messageacknowledge, 将导致异常. 但信息本身还是可用的.

6. 关闭已经closeSession不会导致异常.

 

l         Session的一般使用方式

1. 一种方式: 具有一个同步Consumer的线程, 会阻塞直到有消息到达. 收到消息后, 该线程会使用与Consumer同一个session下的一个或者多个Producer去发消息. 换言之, 这种方式可以用来模拟了这样一套流程: 等待request ==>> 接收到request ==>> 返回response.

2. 另一种方式: 由一个线程setup一个Session, 以及其若干消息Producer, 若干异步Consumer. 由于单线程, Message Listener执行中, Producer会被exclusive. 另外一点是, Session注册了多个Message Listener, 这些Message Listener会被顺序执行, 安全地共享Session的资源.

3. 如果要求一个线程produce消息, 同时另外一个线程consume消息, client code里面应该使用分开的两个Session. 多数情况下, 通过Sessionspartition, client会更natualsimple, 伸缩性更强, 更有效应对日益增长的complexityconcurrency. 我想, 这也是最佳实践了.

4. Connection处于stop状态, 此时Session正在setup, 在完全准备好前, 客户端无需接收消息, 这是preferred策略, 它消除了setupprocess之间不可预期的冲突.  Connection在接收消息的时候, 创建和配置Session是可以的, 但是, 要注意保证消息Producer,Consumer,Listener创建的顺序. 例如, Message Listener中使用的消息Producer还处于创建之中. 或者由于Message Listener注册顺序错误引起接收消息顺序错误.

 

l         Session Error Pattern

1. 同一个Session之下, 一个线程尝试同步接收, 另外一个线程也在尝试同步接收, 这种用法是错误的. Session是单线程的.

2. 一旦Connection start之后, 注册有一个或者若干个Message ListenerSession, 就会交给传送消息给它的线程来控制. 因而, client code里面用另外的线程来控制将Session及其产生的对象是错误的. 唯一的例外, 是对Session进行关闭.

3. 由于Session单线程(single-thread-of-control)的限制, 注册有Message ListenerSession, 无论控制是交给了传送消息给它的线程, 还是交给了client code中对其进行初始化的线程, 试图使用synchronouly receive是错误的. 亦即, 在同一Session, 同步接收和异步接收不允许Combine.

4. 为一个Session配置多个Message Listener, Connection必须(must be)处于stop状态. 已经注册了一个Message Listener, Session处于传送消息线程的控制之下, 这时候, 客户端线程是不能再对其进行配置的.

 

l         Multiple Sessions

client一般会创建multiple Sessions, 每个Session都会有独立的Producer, Consumer. 对于Pub/Sub模型, 每条消息会交给每个订阅者, 消息传送给一个订阅者不会阻塞发送给其他另外的订阅者. 对于PTP模型, JMS没有具体界定, 对同一条Queue进行并发消息收取者的定义. JMS不禁止JMS提供者对并发消息接收的支持, 因而, 消息delivery到多个QueueReceivers取决于provider的实现. 应用程序depend on multiple QueueReceivers会导致不可移植性. 对于监听同一条Queue的多个Message Listener, 会执行哪一个由provider决定了.

 

l         client code序列(顺序)化执行

虽然Java语言提供内置的多线程支持, 但是编写多线程应用程序仍然是相当困难. 因此, JMSclient code不会多线程执行, 除非client显式要求. 一种方式是定义一个Session, 并顺序化(serializes)异步消息传送(asynchronous delivery of messages). 如果要异步接收消息, client通过一个MessageConsumer注册一个object实现MessageListener接口. 而实际上, 一个Session使用单线程去运行它所有的MessageListeners. 当线程在忙于执行一个Listener, 这个Session其他的Listener的异步消息传送必须等待.

 

l         并发消息传送(Concurrent Message Delivery)

client如果要求并发消息传送, 可以使用multiple sessions. 实际上, 每个SessionListener线程是并发运行. 当一个Session的一个Listener正在执行, 另外一个Session的一个Listener也可以在执行. 要注意的是, JMS不提供并发处理Topic消息集(topic's message set)的设施. client可以使用single Consumer来实现所有多线程逻缉, 然而, 这样做并不可靠. 因为JMS并不提供这种条件下要求的并发transaction处理设施. 不好翻译, 原文如下:

 

JavaTM Message Service Specification V1.1 写道
Note that JMS itself does not provide the facilities for concurrently processing a topic’s message set (the messages delivered to a single consumer). A client could use a single consumer and implement all the multithreading logic needed to concurrently process the messages; however, it is not possible to do this reliably, because JMS does not have the transaction facilities needed to handle the concurrent transactions this would require.

 

分享到:
评论

相关推荐

    EJB中用JMS模拟多线程机制的设计和实现

    EJB中用JMS模拟多线程机制的设计和实现 作者:高燕 李旭伟 文震 来源:工业技术 / 自动化技术、计算机技术收藏本文章 多线程机制是提高系统执行效率的关键,但对于采用EJB技术的服务器端,由于EJB规范限制使用多线程...

    javax.jms.jar

    javax.jms.Session.class javax.jms.ConnectionMetaData.class javax.jms.ExceptionListener.class javax.jms.ServerSessionPool.class javax.jms.ConnectionConsumer.class javax.jms.Topic.class javax.jms....

    jms-1.1.jar(jms工具jar包)

    7. **会话(Session)**:在JMS中,`Session`对象是线程安全的,用于创建消息生产者、消费者以及管理事务。会话可以配置为事务性的,这意味着消息的发送和接收可以作为单个事务处理。 8. **持久化**:JMS允许消息的...

    java.jms.jar JMS需要的JAR包

    8. **会话(Session)**:是线程安全的单线程或多线程上下文,用于创建生产者、消费者以及发送和接收消息。 9. **消息监听器(MessageListener)**:实现监听接口,可以在接收到消息时自动调用指定的方法,实现异步...

    javax.jms包,sun的JMS接口规范包

    4. **连接和会话**:`Connection`接口代表与JMS提供者的连接,而`Session`接口则表示一个线程安全的上下文,用于创建消息生产者、消费者和消息。`Session`有事务支持,可以配置为非事务、单事务或自动提交事务。 5....

    Jms做的一些的demo

    Session是线程安全的,可以用于执行多个并发的消息操作。 4. **创建Destination**:目的地可以是Queue(队列)或Topic(主题)。Queue提供点对点通信,而Topic支持发布/订阅模式。 5. **创建MessageProducer和...

    java JMS代码示例

    `Session`是JMS中的线程安全对象,用于创建消费者、生产者和消息。通常,我们使用`Session.AUTO_ACKNOWLEDGE`模式,意味着消息由JMS自动确认: ```java Session session = connection.createSession(false, ...

    ActiveMQ 中javax.jms的源码 javax.jms-sources-1.1.zip

    4. **Session**:会话接口是线程安全的,它提供了一组同步点,用于处理消息的生产和消费。Session还负责管理事务,可以配置为自动提交或手动提交。 5. **ConnectionFactory**:连接工厂接口用于创建到JMS提供者的...

    jms-1.1.jar

    3. **Session**:代表一个单线程上下文,用于创建消费者、生产者以及消息。 4. **MessageProducer**和**MessageConsumer**:分别用于发送和接收消息。 5. **Destination**:代表消息的目的地,可以是Queue或Topic。 ...

    javax.jms.jar包与JMS实例代码

    6. 关闭资源:完成消息交互后,确保正确关闭Producer、Consumer、Session和Connection,释放资源。 JMS实例代码通常会涉及到异常处理,如JMSException和其他相关的运行时异常,确保在出现问题时能够优雅地处理错误...

    JMS详细讲解

    - **Sessions**:每个Session是单线程的,用于创建MessageProducer(消息发送者)和MessageConsumer(消息接收者)。Session还支持消息监听器。根据需求,可以选择不同的确认模式(如 AUTO_ACKNOWLEDGE 或 CLIENT_...

    jms1.1.jar.zip

    3. Session:线程安全的工作单元,用于创建MessageProducer、MessageConsumer以及发送和接收消息。 4. MessageProducer:负责创建和发送消息。 5. MessageConsumer:负责接收消息。 6. Message:表示JMS中的消息对象...

    JMS1.1规范(中文)

    5. **会话(Session)**:会话是JMS中的一条单向通信链路,用于在生产者和消费者之间传递消息。会话是线程安全的,并且可以设置为事务性或非事务性,以控制消息的可靠传递。 6. **目的地(Destination)**:目的地...

    JMS 规范(英文)

    1. **接口与实现**:JMS定义了一系列接口,如`javax.jms.Connection`、`javax.jms.Session`、`javax.jms.MessageProducer`和`javax.jms.MessageConsumer`等,这些接口由具体的JMS提供者实现。开发人员通过调用这些...

    JMS--J2EE培训材料

    4. **创建MessageProducer和MessageConsumer**:使用Session和Destination创建所需的MessageProducer和MessageConsumer。 5. **启动Connection**:最后启动Connection,此时消息开始流动,应用程序即可发送和接收...

    JMS入门文档,JMS入门文档

    - **Session**:在连接内创建的线程安全的上下文,用于创建消息消费者和生产者。 - **MessageProducer**和**MessageConsumer**:用于发送和接收消息的接口。 - **Destination**:表示消息的目标,可以是Queue或...

    weblogic中使用JMS发送和接受消息

    WebLogic Server是一款由Oracle公司提供的企业级应用服务器,它支持Java Message Service (JMS) 规范,允许在分布式环境中可靠地发送和接收消息。JMS是Java平台上的标准接口,用于实现应用程序间的异步通信。本文将...

    JMS规范培训教程 中文版

    ConnectionFactory用于创建连接,Connection代表与消息代理的会话,Session是线程安全的工作单元,Destination是消息的目标,MessageProducer和MessageConsumer分别用于发送和接收消息。 在实际应用中,JMS常用于...

    JMS详细实例学习教程

    Sessions:Sessions 是单线程的,用来创建消息发送者和消息接受者的上下文。Sessions 同时还可以执行 Message Listeners。 3. JMS Provider 和 JTA 的关系 JMS 客户端可以用 JTA 启动事务。JMS Provider 可以选择...

Global site tag (gtag.js) - Google Analytics