我想使用一个使用单个线程的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
的文档很好地概述了您的不同选项。