Java 消息传递(如JMS)何时是多线程的替代方案?

Java 消息传递(如JMS)何时是多线程的替代方案?,java,multithreading,jms,jboss-mdb,message-passing,Java,Multithreading,Jms,Jboss Mdb,Message Passing,我在一个数据处理应用程序上工作,在该应用程序中,通过将多个工作单元放在消息驱动bean(MDB)的多个实例侦听的消息队列上来实现并发性。除了以这种方式实现并发,我们没有任何特定的理由使用消息传递基础结构和MDB 这让我想到了为什么使用多线程无法实现同样的效果 所以我的问题是,在什么情况下可以使用异步消息传递(例如JMS)作为多线程的替代方法来实现并发性?使用一种方法比另一种方法有哪些优点/缺点。它不能作为多线程的替代方法,它是实现多线程的一种方法。这里有三种基本的解决方案: 您负责队列的两端 你

我在一个数据处理应用程序上工作,在该应用程序中,通过将多个工作单元放在消息驱动bean(MDB)的多个实例侦听的消息队列上来实现并发性。除了以这种方式实现并发,我们没有任何特定的理由使用消息传递基础结构和MDB

这让我想到了为什么使用多线程无法实现同样的效果


所以我的问题是,在什么情况下可以使用异步消息传递(例如JMS)作为多线程的替代方法来实现并发性?使用一种方法比另一种方法有哪些优点/缺点。

它不能作为多线程的替代方法,它是实现多线程的一种方法。这里有三种基本的解决方案:

  • 您负责队列的两端
  • 你负责发送数据;或
  • 您负责接收数据
  • 接收数据是这里的关键,因为如果没有某种形式的多线程/多处理,就无法做到这一点,否则一次只能处理一个请求。在不使用多线程的情况下发送数据更为可行,但实际上,您只是将处理这些消息的责任推给了外部系统。因此,它不是多线程的替代方案


    在使用消息驱动bean的情况下,容器为您创建和管理线程,因此它不是多线程的替代方案,您只是使用其他人的实现。

    性能方面的多线程应该比任何消息传递都快,因为您使用消息传递添加了额外的网络层。
    基于应用程序的消息传递可帮助您避免锁定和数据共享问题,因为没有通用对象。

    从扩展的角度来看,消息传递要好得多,因为您可以通过配置消息服务而不是更改应用程序来配置多个服务器上的更多节点。

    消息传递可以大大减少多线程应用程序中的错误数,因为它降低了数据争用的风险。它还简化了添加新线程的过程,而无需更改应用程序的其余部分


    尽管我认为JMS在这里有点误用。java.util.concurrent的线程安全队列和库(如)可能会为您提供更好的性能。

    实际上,在EJB容器中,没有其他选择,因为不允许您在EJB容器中创建自己的线程。JMS正在为您完成所有这些工作,代价是通过队列处理器运行它。您还可以创建一个Java连接器,它与容器有更密切的关系(因此,可以有线程),但这需要做更多的工作


    如果使用JMS队列的开销对性能没有影响,那么这是最简单的解决方案。

    我认为还有两个额外的好处没有提到:事务持久性


    虽然它不是必需的,而且通常不是默认配置,但可以将JMS提供程序配置为持久化消息,并参与XA事务,而代码更改很少或没有更改。

    使用多线程,您可以通过共享CPU核心来实现并发性。但是如果改用JMS,则可以平衡负载并将任务委托给其他系统。 e、 假设您的应用程序要求在完成某项任务时发送电子邮件。并且您希望同时发送电子邮件。您可以拉取线程并异步处理它。或者,您可以使用JMS将此邮件发送任务委托给其他系统。在jms中不能配置任何接收器线程。此外,多个节点可以侦听相同的JMS队列,以平衡负载。您还可以根据应用程序使用其他应用程序,如持久队列、事务管理队列


    简单地说,JMS可以更好地替代多线程,这取决于应用程序体系结构

    从技术上讲,您不应该在J2EE容器中创建线程,但在Web容器中创建线程是很常见的。J2EE规范应该更多地被视为指导原则而不是规则。毕竟,它也不允许直接访问文件系统,但人们总是使用配置文件等来访问文件系统。特别是在使用Spring时。在大多数情况下,异步消息传递是多线程的。是的,这是一种很好的解耦系统/模块的方法。它使一个系统对服务器崩溃等技术问题更具弹性。