【问题标题】:Run parallel tasks in a long running application在长时间运行的应用程序中运行并行任务
【发布时间】:2016-10-07 01:37:05
【问题描述】:

我正在构建一个长时间运行的应用程序,它被建模为基于面向服务架构的服务。将此称为“服务A”。每当对其进行 API 调用时,它就有一个要执行的活动,即调用“activityA”。

activityA 有一个必须并行执行“n”个任务的活动处理程序,之后它会合并并将结果返回给调用 serviceA API 的客户端。

我打算使用 ExecutorService 来实现这种并行性。

有两种方法可以继续:

  1. 在单例范围内创建 ExecutorService,并将其作为活动处理程序的属性。因此,这个相同的 ExecutorService 对象在服务的整个生命周期中都是可用的。当一个新的请求到来时,处理程序使用这个 ExecutorService 对象来提交并行任务。然后等待 Future 对象一段时间。在所有并行任务完成后,合并并返回 activityA 响应。

  2. 每次收到对 activityA 的请求时,在活动处理程序中创建新的 ExecutorService 对象。向该对象提交并行任务,等待一定超时时间的Future结果,合并结果,在ExecutorService对象上调用shutdown,返回activityA API响应。

因此,

  1. 应遵循上述两种方法中的哪一种?两者的主要区别在于 ExecutorService 对象的生命周期。

  2. 该服务应该以每秒约 15,000 个事务量调用,如果此数据有助于通过 2 种方法进行决策吗?

  3. 第一种方法的优点是我们不会有创建和关闭新的 ExecutorService 对象和线程的开销。但是,当超时时间之前没有 Future 结果时会发生什么?线程会自动关闭吗?它是否可用于将进入 ExecutorService 线程池的任何新请求?或者它会处于某种等待状态,并耗尽内存——在这种情况下,我们需要手动做一些事情(以及什么)?

  4. 另外,我们调用 future.get() 时的超时时间是从我们进行此 get 调用的时间开始,还是从我们将任务提交给执行程序服务的时间开始?

如果这两种方法中的任何一种是解决此问题的明显方法,请告诉我。

谢谢。

【问题讨论】:

  • 我认为,它可以帮助你reactivex.io/documentation/observable.html RxJava 是执行并行任务的最佳解决方案之一,当然它比重新发明轮子更好。
  • 感谢伊万的建议!可能会调查它。但就目前而言,我想坚持使用 ExecutorService,因为该项目的周转时间较短。

标签: java parallel-processing threadpool executorservice java.util.concurrent


【解决方案1】:
  1. 第一种方法看起来是解决此问题的明显且正确的方法,尤其是在给定交易量的情况下。你当然不想重启线程。

  2. Future.get 超时不影响正在执行的线程。它将继续运行任务,直到它完成或引发异常。在那之前,它不会接受新任务(但同一执行程序中的其他线程会接受)。在这种情况下,您可能希望通过调用 Future.cancel 来显式取消它,以释放线程以执行新任务。这要求任务本身正确响应中断(例如,而不是永远循环,或者等待 I/O 阻塞)。但是,这对于 any 线程方法是相同的,因为无论如何中断是终止线程的唯一安全方法。要缓解此问题,您可以使用最大运行线程数超过n 的动态线程池。这将允许在卡住的任务正在终止时处理新任务。

  3. 从你打电话的时候开始。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    相关资源
    最近更新 更多