【问题标题】:Is there something that behaves like .wait() and .notify() in EJB environment?在 EJB 环境中是否有类似 .wait() 和 .notify() 的行为?
【发布时间】:2012-02-24 10:30:42
【问题描述】:

我知道我不能修改 EJB 容器中的线程,因此我不知道如何在 EJB 环境中以正确的方式执行以下操作:

参与人员

  • 无状态会话 Bean“客户端”
  • 无状态会话 Bean“服务器”
  • 消息队列“队列”
  • 消息驱动 Bean“Mdb”,它处理来自“队列”的消息
  • n 无状态会话 Bean W1 到 Wn

场景是

Client 调用Server 的方法,该方法又向Queue 发送若干消息。之后,Server 会做一些其他的事情。同时,Mdb 消费一条消息,调用 Wi 进行一些相当长的计算,并得到结果。现在Mdb 将结果提供给Server。当 Server 获得它发送的每条消息的所有“结果”时,它会使用 W 的结果进行更多计算,并将结果返回给 Client .

我的问题

在 Java SE 中,我只需 .wait() 让 ServerServer 之后等待 W 的结果发送消息后的工作。然后 mdb 将在设置结果时 .notify() 。由于我不能修改 EJB 容器中的线程,正如规范所述,我迷失了,因为我没有找到任何合适的方法来在 EJB 环境中实现相同的行为。

对于这个问题的任何帮助将不胜感激,在此先感谢。

P.S.:我正在使用 JBoss 5.1.0,以防有任何供应商特定的措施来解决这个问题。

【问题讨论】:

    标签: java multithreading ejb


    【解决方案1】:

    什么对象充当 MDB 返回所有消息的服务器?它可能需要某种 CountDownLatch 来等待,消息数量的大小(由 MDB 更改直到达到零)。当它变为零时,它会唤醒可以运行返回客户端的代码。 请参阅 CountDownLatch 的 API 文档。

    【讨论】:

    • 你不应该在 J2EE 世界中使用像 CountDownLatch 这样的东西,与等待/通知相同的问题。
    • 我猜这是对另一个线程的讨论。因为 J2EE 仍然是 Java - 是的,你可以,如果你仍然需要使用线程,你必须设计你的应用程序,以便它能够支持这样的代码。
    • 实际上,取决于应用服务器,不,你不能。规范不允许使用此类工具,并且一些应用服务器实际上通过自定义 SecurityManagers 强制执行此操作(在 jvm 支持的范围内)。
    • 更不用说因为它“恰好在我的测试中工作”而轻率地忽略规范是创建代码的好方法,其中潜在的错误等待在生产中弹出。
    【解决方案2】:

    对此的适当解决方案是消息传递的“请求/响应”模式。简而言之,您可以通过消息传递系统执行“同步”操作,方法是发送消息并等待响应消息(所有这些在 J2EE 世界中都是合法的)。在实践中,您可以通过多种方式实现此目的,但总体思路是您发送带有某种唯一标识符的请求消息,然后使用为您的请求 ID 设置的消息过滤器等待响应消息发送(这通常是 "correlationId" field 的用途)。 MDB 将获取请求消息,处理它们,并使用请求消息中指定的唯一标识符发送响应消息。你可以用一个队列来完成所有这些,或者你可以使用单独的请求/响应队列,或者你可以做一些疯狂的事情,比如创建"temporary" response queues(每个请求)。您可以使用Message.setJMSReplyTo 方法告诉M​​DB 将请求消息发送到哪里。

    一般模式是:

    1. 客户端调用服务器
    2. 服务器:
      1. 创建消息,设置correlationId 和replyTo
      2. 创建 QueueSender,发送消息
    3. mdb(对每条消息重复):
      1. 收到消息
      2. 处理消息
      3. 发送带有correlationId的响应消息
    4. 服务器:
      1. 使用correlationId 创建消息过滤器
      2. 使用消息选择器创建 QueueReceiver
      3. 调用receive(),直到收到并处理所有消息(或超时)
      4. 进行最终处理,响应客户端

    (很明显,服务器直接从第2步到第4步,我就是这样写来突出控制流的。)

    【讨论】:

    • 好的,这与我的想法相似,但我最大的问题是“然后等待响应消息”部分。那就是我在 SE 中使用等待通知的地方。所以我正在寻找 MDB 的实际等待机制。你对此有什么暗示吗?
    • @Daniel - 您将设置 MessageConsumer 并在其上调用 receive()。这是等式的“等待”部分。您没有使用 MDB 进行最终处理,仅使用分布式工作。
    • 是否存在服务器错过来自 MDB 的消息的竞争条件,该消息在服务器调用 receive() 之前完成?
    • @increment1 - 有主题,有队列,没有。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-18
    • 1970-01-01
    • 2017-08-21
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多