0

我正在使用 Thread Pool Executor 更改遗留设计。详细情况如下:-

旧版:- 在旧版设计的情况下,在应用程序启动时创建 600 个线程。并放置在各种池中,然后在需要时将其拾取并将任务分配给相应的线程。

新:-在新设计中,我用执行器服务替换了线程池

 ThreadPoolExecutor thpool = new ThreadPoolExecutor(coreSize,poolsize,...);

我观察到的是,在 Executor 的情况下,在启动时没有创建线程。它们是在客户端发出请求时创建的。因此,与前一个相比,在内存中创建的线程要少得多。

但我的问题是这是正确的方式,因为线程创建也是触发调用时发生的开销。

请告诉哪个更重,在从客户端调用时处理线程创建或按照旧方法在内存中存在空闲线程。

还建议使用哪个 Executor 池,以便在性能方面获得最佳结果。

4

3 回答 3

1

要在启动时修复 600 个线程,请尝试使用java.util.concurrent.Executors.newFixedThreadPool( 600 );

创建一个线程池,该线程池重用在共享无界队列上运行的固定数量的线程。在任何时候,最多 nThreads 个线程将是活动的处理任务。如果在所有线程都处于活动状态时提交了其他任务,它们将在队列中等待,直到有线程可用。如果任何线程在关闭之前的执行过程中由于失败而终止,如果需要执行后续任务,新的线程将取代它。池中的线程将一直存在,直到显式关闭。

如您所见,文档并没有告诉我们线程是立即启动还是按需启动。

如果您绝对希望在启动时启动 600 个线程,您可以发布 600 个空任务:

for( int i = 0; i < 600; ++i ) {
   executor.submit( new Runnable(){public void run(){/**/}});
}
于 2013-09-29T09:04:24.770 回答
0

you can call :

thpool.prestartAllCoreThreads();

or

thpool.prestartCoreThread();

This two methods to Starts a core thread (Threads), causing it to idly wait for work.

But i recommended do not do this, it's will be head over on your resources.

于 2013-09-29T09:36:01.843 回答
0

600听起来很多。您可能希望将其降低到可用处理器的数量。或者,如果线程最终等待了很多,Runnables那么如果您的线程不是 100% 受 CPU 限制的,则将 TPE 的平均负载考虑在内。假设您在线程上具有nCPUs=Runtime.getRuntime().availableProcessors()loadFactor作为您的平均负载(如在测试中观察到的,或者更好的是,持续监控中观察到的)。然后你会使用 nThreads=nCPUs/loadFactor 并希望 loadFactor 不为零。

您也可以使用较小的 coresize 和较大的 poolsize,但是您需要一个有界队列。在这种情况下,如果队列已满,TPE 将启动新线程,直到达到 poolsize。如果你的大部分工作都是在 coresize 内处理的,线程创建不应该太频繁,开销也不应该是一个问题。但是,当 TPE 运行其最大线程时,即使这样最终也可能会阻塞。

如果您的作业是某种传入工作,例如从不得阻塞的其他连接的套接字读取,您可以创建一个无界中间队列以释放入站处理最终在您的 TPE 上阻塞,并使用另一个线程从中间提交作业到 TPE 队列。

于 2013-09-29T10:10:02.883 回答