2013-10-04 56 views
2

我正在使用ThreadPoolexecutor通过用传统线程替换它。线程池执行程序的优化-java

我已经创建执行如下:

pool = new ThreadPoolExecutor(coreSize, size, 0L, TimeUnit.MILLISECONDS, 
     new LinkedBlockingQueue<Runnable>(coreSize), 
     new CustomThreadFactory(name), 
     new CustomRejectionExecutionHandler()); 
pool.prestartAllCoreThreads(); 

这里磁芯尺寸是maxpoolsize/5。我已经预先启动了大约160个线程启动应用程序的所有核心线程。

在传统设计中,我们创建并开始围绕670个线程。

但问题是,即使在使用Executor并创建和替换旧版设计之后,我们并没有得到更好的结果。

对于结果内存管理,我们使用top命令来查看内存使用情况。 我们已经在millis中放置了System.currentTime的记录器来检查使用情况。

请告诉如何优化此设计。谢谢。

+1

你并没有给我们太多的工作在这里。我会说你错过了一个助焊剂电容器。 –

回答

3

但问题是,即使使用Executor并创建并替换旧版设计,我们也没有得到更好的结果。

我假设你正在看你的应用程序的整体吞吐量,你是不是看到了更好的性能,而不是在自己的线程运行的每个任务 - 即不与池?

这听起来像你没有因上下文切换而被阻止。也许你的应用程序是IO绑定的或以其他方式等待其他系统资源。 670个线程听起来很多,你会使用大量的线程堆栈内存,否则它可能不会阻止你的应用程序的性能。

通常我们使用ExecutorService类不一定是因为它们比原始线程更快但是因为代码更容易管理。并发类会从您的手中处理大量的锁定,排队等。

夫妇代码注释:

  • 我不知道你想要的LinkedBlockingQueue由核心大小的限制。这是两个不同的数字。 core-size是池中的最小线程数。 BlockingQueue的大小是多少个作业可以排队等待一个空闲线程。

  • 顺便说一句,在ThreadPoolExecutor绝不会分配一个线程过去核心线程数,除非BlockingQueue满。在你的情况下,如果所有的核心线程都很忙,并且队列已满,并且排队的任务的核心数量是下一个线程分叉的时候。我不需要使用pool.prestartAllCoreThreads();。一旦任务被提交到池中,核心线程就会启动,所以我认为它不会给你带来太多的收入 - 至少不会有长时间运行的应用程序。

对于时间,我们已经把系统的记录器。以毫秒为单位的当前时间来检查使用情况。

请注意这一点。过多的记录器可能会影响应用程序的性能,而不是重新构建它。但我假设你在之后添加了记录器,但你没有看到性能改进。

0

执行程序仅包含线程的创建/使用,所以它没有做任何神奇的事情。

这听起来像你在其他地方有一个瓶颈。你是否锁定一个对象?你有一个单线程资源,每个线程命中?在这种情况下,你不会看到任何行为改变。

您的进程是否受CPU限制?如果是这样,你的线程应该(非常粗略地说)匹配可用处理内核的数量。请注意,您创建的每个线程都会为其堆栈消耗内存,并且如果您要绑定内存,那么创建多个线程对此无济于事。