我正在构建一个长期运行的应用程序,它被建模为基于面向服务架构的服务。将此称为' serviceA'。每当对API进行API调用时,它都会执行一项活动,呼叫' activityA'
activityA有一个活动处理程序,必须执行' n'并行的任务,然后整合并将结果返回给调用serviceA API的客户端。
我打算使用ExecutorService来实现这种并行性。
有两种方法可以继续:
在单例范围内创建ExecutorService,并将其作为活动处理程序的属性。因此,在服务的整个生命周期中都可以使用相同的ExecutorService对象。当新请求到来时,handler使用此ExecutorService对象来提交并行任务。然后在Future对象上等待一定的超时时间。完成所有并行任务后,合并并返回activityA响应。
每次在活动处理程序中收到对activityA的请求时,都会创建新的ExecutorService对象。将并行任务提交到此对象,等待Future结果达到某个超时时间,合并结果,在ExecutorService对象上调用shutdown,并返回activityA API响应。
因此,
应遵循以上两种方法中的哪一种?主要区别不适用2是ExecutorService对象的生命周期。
如果这些数据有助于决策制定2/2
第一种方法的优点是我们不会有创建和关闭新的ExecutorService对象和线程的开销。但是,在超时时间之前没有Future结果会发生什么?线程是否会自动关闭?是否可用于将要进入ExecutorService线程池的任何新请求?或者它将处于某种等待状态,并占用内存 - 在这种情况下,我们手动需要做某事(以及什么)?
此外,我们调用future.get()时的超时时间是从我们进行此调用的时间开始,还是从我们将任务提交给执行程序服务的时间开始?
如果有任何一种方法可以解决这个问题,请告诉我。
感谢。
答案 0 :(得分:1)
第一种方式看起来是解决此问题的明显而正确的方法,尤其是在给定数量的事务中。你当然不想重新启动线程。
Future.get
超时不会影响正在执行的线程。它将继续运行任务,直到它完成或抛出异常。在那之前,它不会接受新任务(但同一执行者中的其他线程将会)。在这种情况下,您可能希望通过调用Future.cancel
来明确取消它以释放新任务的线程。这要求任务本身正确响应中断(而不是永远循环,例如,等待I / O阻塞)。但是,这对于任何线程方法都是一样的,因为中断是终止线程的唯一安全方法。要缓解此问题,您可以使用动态线程池,其最大运行线程数超过n
。这将允许在卡住的任务正在终止时处理新任务。
从你打电话开始。