ThreadPoolExecutor - 在队列之前使用线程

问题描述 投票:0回答:1

我正在用 java 给定的 ThreadPoolExecutor 替换旧线程池。在旧版线程池中,启动时会创建 600 个线程。但在 ThreadPoolExecutor 中,使用核心线程、最大线程和 prestartAllCoreThreads() 的概念,可以限制启动时的线程数量。

现在,

  1. 如果运行的线程少于 corePoolSize,则执行器更愿意添加新线程而不是排队。
  2. 如果 corePoolSize 或更多线程正在运行,Executor 更愿意对请求进行排队而不是添加新线程。
  3. 如果请求无法排队,则会创建一个新线程,除非这会超过 MaximumPoolSize,在这种情况下,任务将被拒绝。

第一种情况是好的,但我想要的是,当使用核心线程时,而不是任务排队(即使在有界队列的情况下,比如大小100)并等待核心线程空闲或队列已满,从非核心池配额创建一个新线程。与实时一样,我的应用程序无法忍受任务在队列中等待的想法。

所以我想要的是 CoreThreads -> Non-CoreThreads -> Queue 而不是 CoreThreads -> Queue -> Non-CoreThreads。

即,如果正在使用核心线程,则创建新线程,并且如果池大小达到最大值,则任务应进入队列并等待任何线程空闲。

现在,一种方法是扩展 ThreadPoolExecutor 类并重写执行方法,但随后我必须几乎复制完整的类。这是我能想到的一种肮脏的方式。任何人都可以建议任何其他方式吗?

注意:我不能使用cachedThreadPool,因为需要限制线程数量。

java threadpoolexecutor
1个回答
4
投票

我在这里看到的更多是设计问题而不是线程包问题。

使用线程来减少延迟或增加吞吐量。假设您要创建 600 个线程,这更多的是增加服务器吞吐量的情况。然而,任何现代服务器都没有 600 个 CPU 核心,您将受到上下文切换的严重影响。让固定数量的线程在一组队列上工作既简单又高效。

如果您确实认为您的情况是合理的,只需创建您自己的接口来包装标准线程池,并在单独的线程上启动时具有一些自定义逻辑。但是,我真的怀疑这会提高您的系统性能。

本质上,除非真的非常合理,否则我认为创建新线程并不是比在实时系统中排队更好的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.