【问题标题】:Java ExecuterCompletionService take.get() from different thread来自不同线程的 Java ExecuterCompletionService take.get()
【发布时间】:2014-05-01 00:27:27
【问题描述】:

在 Java 中,我有一个 Web 服务,它在不同的线程上启动一些长时间运行的进程,这样我就可以在连接超时的情况下返回 http 状态。

我的问题涉及创建一个长时间运行的线程,该线程将简单地运行 ExecuterCompletionService.take.get() 以获取已完成的线程并完成对它们的处理。

如果完成服务是在主线程中创建的,是否可以在该单独的线程中运行获取完成的对象?

EG。

主线程

  1. 创建完成服务
  2. 接受请求并创建长时间运行的进程
  3. 将 Callable 提交到完成服务
  4. 如果一切顺利,返回 HTTP 状态 200

监控线程

  1. 存储对在主线程中创建的完成服务的引用。
  2. 运行completionservice.take.get()
  3. 为已完成的任务生成报告
  4. 重复

有什么我忽略的特别需要担心的吗?比如同步问题。我知道内部完成服务使用阻塞队列。

【问题讨论】:

  • 这样你就有了一个Completion Service,它可以接受多个请求并提交。在另一个线程中,您正在按顺序处理它们(通过调用 get() - get() 将等待当前线程,直到作业完成)。您是否正在尝试重塑 JMS?
  • JMS?我会对此进行更多研究。谢谢你。也不,我只是试图不阻塞 web 服务线程,以便启动进程的 put 请求不会超时。
  • 是的,只要您保留完成服务的单个实例,我认为您的方法没有问题。 JMS/MDB 可以用来解决这类问题。假设您提交了 100 个请求,其中完成了 5 个。现在服务器宕机/崩溃。在您的方法中,所有铰孔请求都消失了。如果您使用 JMS,则无需担心,它将被重新交付,您无需使用 JVM 来存储请求
  • 好的,谢谢您的信息。如果您想将其作为答案,我会接受并感谢您提供 JMS 信息,我将对此进行更多调查。

标签: java concurrency java.util.concurrent


【解决方案1】:

恕我直言,只要您保留一个用于提交多个 Callable Jobs 的 ExecutorCompletionService 实例,我认为您的方法没有问题。

在这种方法中,当服务器宕机/崩溃时,您将丢失正在运行的 Job 结果。您将使用 JVM 内存来保持 Jobs 处于活动状态。同样,这取决于请求的数量和并行运行的作业数量以及完成任务所需的时间。

如果您不需要并行运行所有请求,那么对于您的用例,JMS 将是完美的选择。为了避免长时间运行的进程请求超时,我们可以将作业放在JMS中,稍后您可以通过JMSlistener (Message Listener / MDB )使用作业并一一处理。

【讨论】:

  • 非常感谢您的帮助。 :)
猜你喜欢
  • 2015-10-13
  • 2019-07-14
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-03
相关资源
最近更新 更多