首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java ExecutorService --有时比顺序处理慢?

Java ExecutorService --有时比顺序处理慢?
EN

Stack Overflow用户
提问于 2013-09-19 18:25:46
回答 2查看 2.7K关注 0票数 0

我正在编写一个简单的实用程序,它接受可调用任务的集合,并并行运行它们。我们希望所用的总时间比最长的任务所花费的时间少得多。该实用工具还添加了一些错误处理逻辑--如果任何任务失败,并且该故障可以被视为“可重试”(例如超时或用户指定的异常),那么我们直接运行该任务。

我已经围绕一个ExecutorService实现了这个实用程序。有两部分:

  1. 将所有可调用的任务提交给ExecutorService,存储未来对象。
  2. 在for-循环中,获取()每个未来的结果。在异常情况下,执行“可重试”逻辑。

我编写了一些单元测试,以确保使用此实用程序比按顺序运行任务更快。对于每个测试,我都会生成一定数量的可调用函数,每个测试本质上都是在一个界限内执行一个随机时间的Thread.sleep()。我对不同的超时、不同数量的任务等进行了实验,而且这个实用程序的性能似乎优于顺序执行。

但是当我把它添加到需要这种实用工具的实际系统中时,我看到了变化很大的结果--有时并行执行更快,有时更慢,有时更快,但仍然比最长的单个任务花费更长的时间。

我只是做错了吗?我知道ExecutorService有invokeAll(),但这就吞噬了潜在的异常。我还尝试使用CompletionService来按照任务完成的顺序来获取任务结果,但是它显示了或多或少相同的行为。现在我正在阅读关于闩锁和障碍的文章--这是解决这个问题的正确方向吗?

EN

回答 2

Stack Overflow用户

发布于 2013-09-19 18:32:20

我编写了一些单元测试,以确保使用此实用程序比按顺序运行任务更快。对于每个测试,我都会生成一定数量的可调用程序,每个测试本质上都在绑定内执行一个随机时间的Thread.sleep()

是的,这肯定不是一个公平的测试,因为它既没有使用CPU,也没有使用IO。我当然希望平行睡眠比串行睡眠跑得更快。:-)

但是,当我将它添加到实际系统中时,需要这样的实用程序,我看到了非常可变的结果。

正确的。线程应用程序是否比串行应用程序运行得更快,这在很大程度上取决于许多因素。特别是,受IO绑定的应用程序将不会提高性能,因为它们受到IO通道的约束,因此实际上无法执行并发操作。应用程序所需的处理越多,win就越大,将其转换为多线程。

我只是做错了吗?

如果没有更多的细节就很难知道。您可以考虑使用并发运行的线程数。如果您有大量的任务要处理,您不应该使用Executos.newCachedThreadPool(),而应该根据您的体系结构所拥有的CPU数量来优化newFixedSizeThreadPool(...)

您还可能希望了解是否可以将IO操作隔离在几个线程中,并将处理过程隔离到其他线程。就像一个从文件中读取的输入线程和一个写入数据库的输出线程(或一对)一样。因此,多个大小的池可以更好地处理不同类型的任务,而不是使用单个线程池。

尝试使用CompletionService以完成任务的顺序获取任务结果

如果您要重新尝试操作,那么使用CompletionService就是正确的方法。当作业完成并抛出异常(或返回失败)时,它们可以重新启动并立即放入线程池中。我看不出为什么你的表现会因为这个而出现问题。

票数 3
EN

Stack Overflow用户

发布于 2013-09-19 18:38:12

多线程编程并不是免费的。它有一个开销。超越可以很容易超过和性能增益,通常会使您的代码更加复杂。

额外的线程可以访问更多的cpu (假设您有多余的cpu ),但通常它们不会使您的HDD旋转得更快,给您更多的网络带宽或加快一些不受cpu约束的东西。

多个线程可以帮助您更多地共享外部资源。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18902279

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档