在长时间运行的应用程序中运行并行任务

时间:2016-06-07 08:39:54

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

我正在构建一个长期运行的应用程序,它被建模为基于面向服务架构的服务。将此称为' serviceA'。每当对API进行API调用时,它都会执行一项活动,呼叫' activityA'

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

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

有两种方法可以继续:

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

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

  3. 因此,

    1. 应遵循以上两种方法中的哪一种?主要区别不适用2是ExecutorService对象的生命周期。

    2. 如果这些数据有助于决策制定2/2

    3. ,那么该服务应该以每秒约15k的交易量进行调用。
    4. 第一种方法的优点是我们不会有创建和关闭新的ExecutorService对象和线程的开销。但是,在超时时间之前没有Future结果会发生什么?线程是否会自动关闭?是否可用于将要进入ExecutorService线程池的任何新请求?或者它将处于某种等待状态,并占用内存 - 在这种情况下,我们手动需要做某事(以及什么)?

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

    6. 如果有任何一种方法可以解决这个问题,请告诉我。

      感谢。

1 个答案:

答案 0 :(得分:1)

  1. 第一种方式看起来是解决此问题的明显而正确的方法,尤其是在给定数量的事务中。你当然不想重新启动线程。

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

  3. 从你打电话开始。