ExecutorServices.submit的确切行为是什么(就排队请求而言)



我想使用一个使用单个线程的ExecutorService。现在,我插入请求(通过提交)的速率高于线程处理它们的速率。会发生什么?

我特别想知道:

  • 订单上有任何保证吗?任务会以完全相同的顺序执行吗
  • ExecutiorService开始丢弃传入请求的(理论上)限制是否存在
  • 出于好奇:当服务使用线程池时,会发生什么变化

(当然,我可以假设可能使用了一些队列;Oracle实现只是"做了正确的事情";但我实际上想知道是否有一个真正的"规范"可以确定预期的行为)

如果您使用Executors.newFixedThreadPool(1);(或newSingleThreadExecutor())创建了一个固定线程池ExecutorService,那么Javadoc会清楚地指定发生什么。


订单上有任何保证吗?任务会以完全相同的顺序执行吗?

固定线程池使用LinkedBlockingQueue来保存挂起的任务。这样的队列实现FIFO策略(先进先出),因此执行顺序得到保证。


ExecutorService开始丢弃传入请求的(理论上)限制是否存在?

引用Javadoc:

如果在所有线程都处于活动状态时提交了其他任务,则它们将在队列中等待,直到有线程可用为止。

每个传入请求都将被添加到一个无限制队列中,因此没有限制,也不会拒绝任何请求(因此理论限制为Integer.MAX_VALUE)。


出于好奇:当服务使用线程池时,会发生什么变化?

如果你的意思是,"如果固定线程池中有超过1个线程,会发生什么变化",那么什么都没有。队列仍然具有FIFO性质,并且对该队列没有限制。否则,这取决于如何创建线程池。

我认为您是通过Executors.newSingleThreadExecutor()获得ExecutorService的?

创建一个执行器,该执行器使用在无边界队列中操作的单个工作线程。(但请注意,如果此单个线程在关闭前的执行过程中因故障而终止,则在需要执行后续任务时,将替换一个新线程。)任务保证按顺序执行,并且在任何给定时间都不会有超过一个任务处于活动状态。与其他等效的newFixedThreadPool(1)不同,返回的执行器保证不会重新配置以使用其他线程。

因此:

订单上有任何保证吗?任务会以完全相同的顺序执行吗?

任务保证按顺序执行

ExecutiorService开始丢弃传入请求的(理论上)限制是否存在?

对无边界队列进行操作队列的内存/后备存储所允许的大小。通常为Integer.MAX_VALUE

出于好奇:当服务使用线程池时,会发生什么变化?

取决于创建ExecutorService的方式。如果愿意,您可以使用有界队列创建,也可以使用不使用FIFO的队列(如PriorityBlockingQueue)创建。ThreadPoolExecutor的文档很好地概述了您的不同选项。

相关内容

  • 没有找到相关文章

最新更新