繁体   English   中英

Java 线程池任务执行排队

[英]Java Thread Pool task execution queueing

通过ThreadPoolExecutor使用java线程池时,所有任务在执行前都排队了吗? 还是仅在没有可用线程时才排队(正在运行的线程数等于或高于核心池大小)?

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

在此处输入图像描述

无界队列

关于你的问题,即使一个线程可用,任务也会首先插入队列,然后由选择的空闲线程拉取。 如果没有可用的线程,提交者仍会将任务放入队列中。 在简历中,流程始终是Submitter -> Queue -> Thread

无界队列通常定义最大大小为 INTEGER.MAX_VALUE,这在 99% 的时间内足以避免提交者阻塞。

大小有限的队列

如果队列中没有可用的位置,提交者可以实现不同的机制,例如:

  • Caller-Runs :提交者是运行任务的人。
  • 阻塞行为:提交者可能会尝试将任务插入队列(永远或在超时内,在丢弃之前)。
  • 丢弃策略:队列可以配置为在尝试插入新任务时删除最旧的排队任务。

无论使用何种机制,任务流程(如果一切正常)是:

Submitter -> Queue -> Thread

在更糟糕的情况下,此流程可能是:

Submitter --> Submitter (队列已满和调用者运行)

Submitter --> Queue --> GarbageCollector (队列已满并被丢弃,因为它是最旧的任务)

Submitter --> GarbageCollector (队列已满,重试失败后丢弃)


在任何情况下,流量都不会

Submitter --> Thread

避免提交者和线程池之间的直接连接使该系统具有异步性质,其中队列代表“安全窗口”。 这边走:

  • Submitters永远不会被阻止(使用无界队列)。
  • 仅当队列已满并且该机制实现阻塞行为使用有界队列)时, Submitters者才会被阻塞。
  • Threads不必处理来自任务提交者的直接同步请求。
  • SubmittersThreads避免了复杂的同步机制,因为它们不必直接协商。
  • 如果Submitters因某些错误而停止或被交付停止, Threads仍然可以通过拉取待处理的排队任务来继续工作。
  • 同样,如果Threads停止, Submitters仍然可以继续工作,将任务放入queue中以供将来处理。 (使用无界队列)。

考虑到这一点,监控queue的内容及其最大大小很重要,以避免OOM异常。 如果提交者发送太多任务和/或太快,而线程无法遵循它们的节奏,则可能会发生这种情况。 这将涉及队列内的上升滞后,因此可能出现Out of Memory错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM