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

现在,

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

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

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

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

现在,一种方法是扩展ThreadPoolExecutor类并覆盖execute方法,但随后我几乎要复制完整的类。我想到的是这种肮脏的方式。任何人都可以提出其他建议。

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

最佳答案

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

一种使用线程来减少延迟或增加吞吐量的方法。如果您要创建600个线程,则更多情况下是增加服务器上的吞吐量。但是,任何现代服务器都没有600个CPU内核,因此上下文切换会给您带来严重的痛苦。在一组队列上使用固定数量的线程既简单又高效。

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

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

09-16 04:22