ExecutorService.submit的确切行为是什么(在排队请求方面)?

时间:2015-11-13 10:21:25

标签: java executorservice

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

我特别想知道:

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

(当然,我可以假设某些队列可能会被使用;并且Oracle实现只是“做正确的事情”;但实际上我想知道某个地方是否存在一个真正的“规范”来确定预期的行为)

2 个答案:

答案 0 :(得分:2)

我认为你通过Executors.newSingleThreadExecutor()获得了ExecutorService

  

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

所以:

  

订购是否有任何保证 - 任务是否以完全相同的顺序执行?

保证任务按顺序执行。

  

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

操作无限制队列。因此,与内存一样大,队列的后备存储将允许。通常Integer.MAX_VALUE

  

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

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

答案 1 :(得分:2)

如果您使用ExecutorService(或Executors.newFixedThreadPool(1);)创建了固定的线程池newSingleThreadExecutor(),则the Javadoc会明确指出会发生什么。

  

订购是否有任何保证 - 任务是否以完全相同的顺序执行?

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

  

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

引用Javadoc:

  

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

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

  

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

如果你的意思是“如果固定线程池中有超过1个线程会有什么变化”,那么什么都没有。队列仍然具有FIFO特性,并且该队列没有限制。否则,它取决于您创建线程池的方式。