如何优化线程数以加快处理速度

时间:2013-11-24 16:38:03

标签: java multithreading

我读过很多类似的questions。但是我对答案不太满意。

我想构建一个算法,根据平均速度调整线程数。

让我们说当我引入一个新线程时,任务执行的平均速度会增加,这意味着新线程是好的。然后算法应该尝试添加另一个线程......直到达到最佳线程数.......

此算法也应该跟踪平均速度。如果在某些时候平均速度显着下降,让我们说10%(因为任何原因,例如我打开一个不同的应用程序或其他),那么算法应终止一个线程,看看速度是否上升......

也许存在这样的API。请给我任何指示或任何代码示例我如何实现这样的算法

谢谢!

4 个答案:

答案 0 :(得分:6)

我不知道您正在描述的自调系统,但是一旦您使用准备好的线程池,它听起来就不是那么复杂的任务。从concurrency包获取线程池,实现包装任何其他可调用的类TimeConsumptionCallable implements Callable,并测量执行时间。

现在,您只需在平均执行时间增加或减少时更改(增加或减少)工作线程数。

在决定更改工作线程数之前,请不要忘记您需要足够的统计信息。否则,不依赖于您的应用程序的各种随机效果可能会导致您的线程池一直增长并且一直停止,这本身就会导致整体性能下降。

答案 1 :(得分:5)

newCachedThreadPool() V/s newFixedThreadPool表示您可能应该关注ExecutorService.newCachedThreadPool()

  

创建根据需要创建新线程的线程池,但在可用时重用先前构造的线程。这些池通常会提高执行许多短期异步任务的程序的性能。如果可用,执行调用将重用先前构造的线程。如果没有可用的现有线程,则将创建一个新线程并将其添加到池中。 未使用60秒的线程终止并从缓存中删除。因此,长时间闲置的池不会消耗任何资源。请注意,可以使用ThreadPoolExecutor构造函数创建具有相似属性但不同详细信息的池(例如,超时参数)。

答案 2 :(得分:2)

如果您的线程在任何时候都没有阻塞,那么当您拥有与内核一样多的线程时,可以达到最大执行速度,因为只有100%以上的CPU使用率是不可能的。

在其他情况下,很难衡量一个新线程会增加/减少执行速度的程度,因为你只是观察一个时刻并根据下一秒可能完全不同的事情做出假设。

一个想法是将Executor类与您指定的Queue结合使用。因此,您可以测量队列的大小并根据该假设进行假设。如果队列为空,则线程处于空闲状态,您可以删除一个。如果队列填满,线程无法处理负载,则需要添加更多。如果队列稳定,你就是对的。

答案 3 :(得分:1)

您可以使用java的现有API来提出自己的算法:

  {p <3}}中的

public void setCorePoolSize(int corePoolSize)

设置核心线程数。这将覆盖构造函数中设置的任何值。

如果新值小于当前值,则过多的现有线程将在下次空闲时终止。

如果更大,如果需要,将启动新线程以执行任何排队任务。

初始化:

ExecutorService service = Executors.newFixedThreadPool(5); // initializaiton

根据您的需要,使用以下API

调整池的大小
((ThreadPoolExecutor)service).setCorePoolSize(newLimit);//newLimit is new size of the pool 

还有一点很重要:如果队列已满,且线程数的新值大于或等于前面定义的maxPoolSize,则任务将被拒绝。

设置maxPoolSize时要小心,以便setCorePoolSize正常工作。