在长时间运行的应用程序中运行并行任务
我正在构建一个长时间运行的应用程序,该应用程序被建模为基于面向服务的体系结构的服务。称之为'serviceA'。它有一个活动来执行,每当调用API时调用'activityA'。在长时间运行的应用程序中运行并行任务
activityA有一个活动处理程序,它必须并行执行“n”个任务,然后合并并将结果返回给调用serviceA API的客户端。
我打算使用ExecutorService来实现这种并行性。
有2种方式与此先走:
在单身范围创建的ExecutorService,并将其作为活动的处理程序的属性。因此,同一个ExecutorService对象在服务的整个生命周期中都可用。当新的请求到来时,处理程序使用此ExecutorService对象提交并行任务。然后等待Future对象一定的超时时间。完成所有并行任务后,合并并返回activityA响应。
每次在活动处理程序中收到对activityA的请求时,都会创建新的ExecutorService对象。将并行任务提交给此对象,在某些超时时间内等待Future结果,合并结果,调用ExecutorService对象的关闭并返回activityA API响应。
因此,
哪2以上方法的应遵循?主要区别b/w 2是ExecutorService对象的生命周期。
如果这个数据有助于决策制定,那么该服务应该被称为每秒大约15k个事务处理?
第一种方法的优点是我们不会有创建和关闭新的ExecutorService对象和线程的开销。但是,当超时时间没有未来结果时会发生什么?线程是否自动关闭?它是否可用于任何将要进入ExecutorService线程池的新请求?或者它会处于某种等待状态,并吃掉记忆 - 在这种情况下,我们需要手动做些什么(以及什么)?
另外,我们调用future.get()时的超时时间是从我们进行此调用的时间还是从我们将任务提交给执行程序服务的时间?
请让我知道是否有任何2种方法是明显的方法来解决这个问题。
谢谢。
第一种方式看起来像是解决此问题的明显且正确的方法,尤其是对于给定数量的事务。你当然不想重新启动线程。
Future.get
超时不会影响正在执行的线程。它将继续运行任务,直到它完成或引发异常。在此之前,它不会接受新的任务(但同一执行器中的其他线程将会)。在这种情况下,您可能需要通过调用Future.cancel
来明确取消它以释放新任务的线程。这需要任务本身正确响应中断(而不是永远循环,例如,或等待阻塞I/O)。但是,这对于任何线程方法都是一样的,因为中断是反正终止线程的唯一安全方法。为了缓解这个问题,你可以使用一个动态的线程池,其运行线程的最大数量大于n
。这将允许在阻塞任务正在终止的同时处理新任务。从你叫它的时候开始。
我想,它可能会帮助你http://reactivex.io/documentation/observable.html RxJava是执行并行任务的最佳解决方案之一,当然它更好,然后重新发明*。 – Ivan
谢谢伊凡的建议!可能会研究它。但是现在我想坚持使用ExecutorService,因为项目的周转时间较短。 –