1

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

现在,

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

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

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

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

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

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

4

1 回答 1

3

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

一种使用线程来减少延迟或增加吞吐量。鉴于您正在创建 600 个线程,这更像是增加服务器吞吐量的情况。但是,任何现代服务器都没有 600 个 CPU 内核,您将遭受上下文切换的严重影响。让固定数量的线程在一组队列上工作更容易且更有效。

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

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

于 2013-10-09T06:26:43.220 回答