我正在尝试更改报告的执行并以并发方式完成。在“连续模式”下,执行测试需要 30 秒,而在使用并发模式时,我需要 27 秒(考虑到必须连续执行几个步骤,我对结果没意见)。
我仍然不明白的是这一行:
ExecutorService executor = Executors.newFixedThreadPool(4);
我的计算机配备了 2x2.6 Ghz 四核,如果 newFixedThreadPool 较高 (16),我预计执行时间会减少。实际上,我增加 newFixedThreadPool 的次数越多,执行速度就越慢。这就引出了一个问题:我做错了什么或者我不明白什么?!?!
我嵌入了我执行的 2 个结果截图。
一个。 newSingleThreadExecuter - 在 23 秒内运行
B. newFixedThreadPool(4) - 在 43 秒内运行。
每次我提交“Worker”时,我都会得到 system.out currentTimeMillis,“fatched tkt”结果是从数据库获取数据所需的毫秒数。 (在策略 A 中 - 它需要大约 3 毫秒,而在策略 B 中最多需要 7 毫秒)。
Stopper stopper = new Stopper();
for (Long iNum : multimap.asMap().keySet())
{
List<Long> tickets = (List<Long>) multimap.get(iNum);
for (Long ticketNumber : tickets)
{
pojoPks = getPkData(iNum);
Callable<PojoTicket> worker = new MaxCommThread(ticketNumber, pojoPks);
Future<PojoTicket> submit = executor.submit(worker);
futures.add(submit);
}
}
System.out.println("futurues: " +futures.size());
for (Future<PojoTicket> future : futures)
{
try
{
PojoTicket pojoTicket = future.get();
//do the rest here
} catch (InterruptedException e)
{
System.out.println("---------------------->InterruptedException");
} catch (ExecutionException e)
{
System.out.println("---------------------->ExecutionException");
}
}
executor.shutdown();
stopper.stop();
最佳答案
the more I increase the newFixedThreadPool the slower the execution
一般来说,如果您向作业添加线程但它没有加快速度,则可能是由于以下几个原因之一:
每个作业都必须在某种资源上同步,因此它们都在争夺锁,而不是独立运行。
作业没有太多 CPU 工作要做。向 IO 绑定(bind)进程添加线程不会使事情变得更快,因为 IO channel 可能已经达到极限。
但是,如果您的应用程序运行速度减半,这是一个有趣的情况。我只能猜测是两者的结合。
要尝试的一件事是从 1 个线程开始,然后尝试 2 个。如果它没有运行得更快,那么首先查看作业之间共享的锁。每个作业正在修改哪些并发集合或其他对象?尝试减少锁的数量或让线程存储临时信息,然后锁定一次以更新中心对象。
您还可以查看系统统计信息,了解您的 IO channel 是否已达到极限。磁盘是这里的一个常见问题。查看是否可以在内存磁盘上运行以查看您的应用程序是否运行得更快。这将表明您受 IO 限制。
最后,我会研究为什么当您的作业被收割时您会收到任何 ExecutionException
。这可能是其他问题的一个指标,但您应该首先了解这一点。
关于java - 为什么增加 newFixedThreadPool 会导致性能不佳?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11783150/