【问题标题】:External service fires asynchronous task and immediately returns. How to tell when the tasks are actually finished?外部服务触发异步任务并立即返回。如何判断任务何时真正完成?
【发布时间】:2015-05-11 21:09:57
【问题描述】:

我需要调用一些服务并知道它们何时完成,以便我可以发送通知:

...
someService.doStuff();
otherService.doStuff();
//all services finished
sendOutNotification();

问题在于,其中一些服务异步启动它们的工作并立即从 doStuff() 返回,而不是等待这些工作完成。由于我当前的线程只是调用这些服务方法,而不是拥有这些服务正在创建和触发的任何实际线程管理执行程序,因此似乎无法知道 doStuff() 触发的线程何时完成。

有没有办法解决这个问题?或者这里是否存在设计问题链接异步执行而无需在任何级别(顶部除外)等待?

【问题讨论】:

  • 它是异步的,因此您需要一个 callbank 函数,该函数可以在作业完成时触发。或者进入轮询循环并让作业在完成后设置一个标志。
  • API 应该提供一种通知操作完成的方法。

标签: java concurrency java.util.concurrent


【解决方案1】:

当你到达一个在所有异步工作完成之前你不能通过的点时,你需要轮询异步任务的完成,或者有一些机制来阻止它们的完成。

解决这个问题的一个不错的方法是通过ExecutorService 执行您的任务,并将生成的Future 对象作为句柄提供给主线程。也就是说,您的 doStuff() 方法将返回这些。您的主要方法收集Futures,到时候可以通过Future.isDone() 进行轮询,通过Future.get() 阻止完成,等等。

【讨论】:

    【解决方案2】:

    最好的方法是使用“回调”。因此,当您调用外部服务时,请发送服务侦听器(如果外部服务支持这种类型的协定)。回调或侦听器在完成时由外部服务调用。

    否则,您可以将这些 API 与期货一起使用。使用.get() 您可以检查它们的完成状态。要同步它们的操作,您可以使用倒计时锁存器,这样当所有线程返回时,倒计时锁存器变为 0,您可以执行操作。

    【讨论】:

      【解决方案3】:

      参考:http://markusjais.com/understanding-java-util-concurrent-completionservice/

      如果 ext lib 不支持回调,可能是 Java 的 Completion Service 可以为你做一些事情。

      将您的所有doStuff 任务提交给完成服务,并为所有任务使用take()。一旦take() 为所有提交的任务返回(除非队列中存在完成服务在任务完成后放入的元素,否则将被阻塞)

      一旦take()为所有任务返回,就可以触发通知。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-10
        • 1970-01-01
        • 2020-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多