简体   繁体   English

消息传递(例如JMS)什么时候可以替代多线程?

[英]When is messaging (e.g. JMS) an alternative for multithreading?

I work on a data processing application in which concurrency is achieved by putting several units of work on a message queue that multiple instances of a message driven bean (MDB) listen to. 我在一个数据处理应用程序上工作,该应用程序通过将多个工作单元放在消息队列上来实现并发性,消息驱动bean(MDB)的多个实例都在侦听该队列。 Other than achieving concurrency in this manner, we do not have any specific reason to use the messaging infrastructure and MDBs. 除了以这种方式实现并发外,我们没有使用消息传递基础结构和MDB的任何特定原因。

This led me to think why the same could not have been achieved using multiple threads. 这使我思考为什么使用多个线程无法实现相同的目的。

So my question is, in what situations can asynchronous messaging (eg JMS) be used as an alternative to mutithreading as a means to achieve concurrency ? 因此,我的问题是,在什么情况下可以使用异步消息传递(例如JMS)替代多线程作为实现并发的手段? What are some advantages/disadvantages of using one approach over another. 使用一种方法相对于另一种方法有哪些优点/缺点?

It can't be used as an alternative to multithreading, it is a way of of implementing multithreading. 它不能用作多线程的替代方法,它是一种实现多线程的方法。 There are three basic kinds of solutions here: 这里有三种基本的解决方案:

  1. You are responsible for both ends of the queue; 您应对队列的两端负责;
  2. You are responsible for sending data; 您负责发送数据; or 要么
  3. You are responsible for receiving data. 您负责接收数据。

Receiving data is the kicker here because there's really no way of doing that without some form of multithreading/multiprocessing otherwise you'll only be processing one request at a time. 接收数据是这里的关键,因为如果没有某种形式的多线程/多处理,实际上是无法做到这一点的,否则您一次只能处理一个请求。 Sending data without multithreading is much more viable but there you're only really pushing the responsibility for dealing with those messages to an external system. 在不使用多线程的情况下发送数据要可行得多,但实际上您只是将处理这些消息的责任推到了外部系统上。 So it's not an alternative to multithreading. 因此,它不是多线程的替代方案。

In your case with message driven beans, the container is creating and managing threads for you so it's not an alternative to multithreading, you're simply using someone else's implementation. 在使用消息驱动bean的情况下,容器正在为您创建和管理线程,因此它不是多线程的替代选择,您只是在使用其他人的实现。

There are two additional bonuses that I don't think has been mentioned: Transactions and durability . 我认为还没有提到另外两个奖励: 交易持久性

While it isn't required and quite often isn't the default configuration, JMS providers can be configured to persist the messages and also to participate in a XA transaction with little or no code changes. 虽然不是必需的,而且通常不是默认配置,但可以将JMS提供程序配置为持久保留消息,并且只需很少或不更改代码即可参与XA事务。

In an EJB container, actually, there is no alternative, since you're not allowed to create your own threads in an EJB container. 实际上,在EJB容器中没有其他选择,因为不允许您在EJB容器中创建自己的线程。 JMS is doing all of that work for you, at a cost of running it through the queue processor. JMS正在为您完成所有这些工作,但需要通过队列处理器运行它。 You could also create a Java Connector, which has a more intimate relationship with the container (and thus, can have threads), but it's a lot more work. 您还可以创建一个Java连接器,该连接器与容器之间的关系更加密切(因此可以具有线程),但这需要做很多工作。

If the overhead of using the JMS queue isn't having a performance impact, then it's the easiest solution. 如果使用JMS队列的开销不会对性能造成影响,那么它是最简单的解决方案。

Performance-wise multi-threading should be faster than any messaging, because you add an additional network layer with messaging. 在性能方面,多线程应该比任何消息传递都要快,因为您在消息传递中添加了额外的网络层。
Application-wise messaging helps you to avoid locking and data sharing issues as there is no common object. 基于应用程序的消息传递可帮助您避免锁定和数据共享问题,因为没有通用对象。
From a scaling perspective messaging is a lot better as you can configure just more nodes on several server by configuring the message service instead of changing the application. 从扩展角度看,消息传递要好得多,因为您可以通过配置消息服务而不是更改应用程序来在多个服务器上仅配置更多节点。

Messaging can reduce number of errors in multithreaded applications greatly, since it reduces risk of data races. 消息传递可以减少数据争用的风险,因此可以大大减少多线程应用程序中的错误数量。 It also simplifies adding new threads without changing the rest of app. 它还简化了添加新线程的过程,而无需更改其余的应用程序。

Although I think JMS is slightly misused here. 尽管我认为JMS在这里有一些误用。 java.util.concurrent's thread-safe queues and libraries like jetlang may provide you better performance. java.util.concurrent的线程安全队列和类似jetlang的库可以为您提供更好的性能。

Using multi-threading you can achieve concurrency by sharing core of CPU. 使用多线程可以通过共享CPU核心来实现并发。 But if you use JMS instead you can balance the load and can delegate the task to other system. 但是,如果改用JMS,则可以平衡负载并将任务委派给其他系统。 eg Suppose your application demands to send email on completion of certain task. 例如,假设您的应用程序要求在完成某些任务时发送电子邮件。 And you want to send email concurrently. 而且您想同时发送电子邮件。 Either you can pull a thread and process it asynchronously. 您可以拉出一个线程并异步处理它。 Or you can delegate this task of mail sending to other system using JMS. 或者,您可以委派使用JMS将邮件发送到其他系统的任务。 No of receiver threads can be configurable in jms. 接收器线程数不能在jms中配置。 Also multiple nodes can listen to same JMS queue which balance the loads. 而且,多个节点可以侦听相同的JMS队列,以平衡负载。 And you can use further applications like persistent queue, transaction managed queue as per application. 您可以根据应用程序使用其他应用程序,例如持久队列,事务管理队列。

In simple words, JMS can be better alternative to multi-threading depends on application architecture 简而言之,取决于应用程序体系结构,JMS可以更好地替代多线程

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在RBDMS或NOSQL数据存储区或其他消息传递系统(例如,rabbitmq)之上实现分布式队列类似的东西? - How could a distributed queue-like-thing be implemented on top of a RBDMS or NOSQL datastore or other messaging system (e.g., rabbitmq)? 在例如Chord环中绘制节点 - Draw nodes in e.g. a Chord ring IDE中的智能注释(例如Netbeans) - Smart commenting in an IDE (e.g. Netbeans) JMS中的多线程 - Multithreading in JMS 当屏障(例如CyclicBarrier)通过的线程量小于屏障限制时,会导致死锁吗? - Does barrier (e.g. CyclicBarrier) cause deadlock when the amount of thread passed it is smaller than the barrier limit? 如何为Android应用创建标题屏幕? 例如,当应用程序像Facebook一样加载时 - How do you create a title screen for an android app? E.g. When the app is loading like Facebook 当每个“绘图”仅使用一位(例如,对nextBoolean的调用)时,为什么不缓存伪随机位? - Why are pseudorandom bits not cached when only one bit is used per “draw” (e.g. a call to nextBoolean)? 当路径包含任何空格(例如,%20)时,无法在Java ist中加载文件 - Loading files in a Java ist not working when path contains any whitespaces e.g. %20 为什么在某些事件中调用getLayoutParams()会引发异常? 例如onSaveInstanceState - Why does getLayoutParams() throw exception when called inside some events? e.g., onSaveInstanceState 测试失败时记录异常的最佳方法(例如使用junit规则) - Best way of logging exceptions when tests fail (e.g. using a junit rule)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM