java线程池任务执行排队

yhived7q  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(734)

当通过threadpoolexecutor使用java线程池时,所有任务在执行之前是否都已排队?或者只有在没有线程可用时它们才排队(运行的线程数等于或大于核心池大小)?

n9vozmp4

n9vozmp41#

任务提交者总是将任务发送到队列(或尝试发送),因为它们与池线程之间没有直接连接(这是有充分理由的)。

无界队列
关于您的问题,即使线程可用,任务也将首先插入队列,然后由choosen free线程拉入。如果没有可用的线程,提交者仍然会将任务放入队列中。在简历中,流程总是 Submitter -> Queue -> Thread .
无界队列通常定义integer.max\u值的最大大小,这在99%的时间内足以避免提交程序块。
大小受限的队列
如果队列中没有可用的位置,提交者可以实现不同的机制,例如:
调用者运行:其中提交者是运行任务的人。
阻塞行为:提交者可能尝试将任务插入队列(永远或在一个超时时间内,然后丢弃它)。
丢弃策略:如果尝试插入新任务,则可以将队列配置为删除最旧的排队任务。
无论使用何种机制,任务流程(如果一切正常)都是: Submitter -> Queue -> Thread .
在更糟糕的情况下,这种流动可能是: Submitter --> Submitter (队列已满,呼叫方运行) Submitter --> Queue --> GarbageCollector (队列已满,已丢弃,因为它是最早的任务) Submitter --> GarbageCollector (队列已满,重试失败后丢弃)
在任何情况下,流量都不会 Submitter --> Thread 避免提交者和线程池之间的直接连接使系统具有异步特性,其中队列表示“安全窗口”。这种方式: Submitters 从未被阻止(使用无界队列)。 Submitters 仅当队列已满且机制实现阻塞行为(使用有界队列)时,才会阻塞。 Threads 不必处理来自任务提交者的直接同步请求。 Submitters 以及 Threads 避免复杂的同步机制,因为它们不必直接协商。
如果 Submitters 由于某种错误而停止或被完全停止, Threads 仍然可以通过提取挂起的排队任务继续工作。
同样,如果 Threads 都停止了, Submitters 仍然可以继续工作,将任务放置在 queue 以备将来处理(使用无界队列)。
考虑到这一点,监控 queue 的内容及其最大大小,是为了避免 OOM 例外情况。如果提交者发送太多任务和/或太快,而线程无法遵循其节奏,则可能发生这种情况。这将涉及队列内部的上升延迟,因此 Out of Memory 错误。

相关问题