我想使用使用单个线程的ExecutorService
。现在我插入请求(通过提交)的速率高于该线程可以处理它们的速率。会发生什么?
我特别想知道:
(当然,我可以假设某些队列可能会被使用;并且Oracle实现只是“做正确的事情”;但实际上我想知道某个地方是否存在一个真正的“规范”来确定预期的行为)
答案 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特性,并且该队列没有限制。否则,它取决于您创建线程池的方式。