3

我有一些代码大量使用线程池,我通过创建Collection<Callable<T>> tasks和调用来使用线程池ExecutorService.invokeAll(tasks)

for (Future<Object> future : threadPool.invokeAll(tasks)) {
  Object object = future.get();
  // Calling thread effectively blocks on invokeAll().
}

在我的应用程序中,大小tasks变化很大。事实上,大多数情况下都是用单个任务ExecutorService.invokeAll()调用的。我正在使用的实现调用,其实现似乎总是在线程池中运行任务(从不在调用线程中)。invokeAll()ThreadPoolExecutor.execute()

在单个任务的情况下,在当前线程中调用任务而不是将其发送到另一个线程会更有效吗?

4

2 回答 2

3

在单个任务的情况下,在当前线程中调用任务而不是将其发送到另一个线程会更有效吗?

是的,这样会更有效率。不过,这不是一个有趣的问题。有趣的问题是它的效率有多低——这取决于你的任务在做什么——以及你是否在你的应用程序中做了足够多的事情以使其在整体上很重要。

我们没有足够的信息来为您评估。如果您每秒执行数百万次单个琐碎任务(“从地图中获取值”),那么通过线程池的所有间接操作都会产生真正的影响。如果您的任务实际上做了大量工作,那么几乎可以肯定不值得额外的代码来处理您只有一个任务的情况。

于 2012-06-27T06:01:25.770 回答
2

当然,如果你只是在原地运行它,执行某些代码的总成本将会有所降低。您不是在构建集合、排队和出队、唤醒工作线程、在 CPU 必须分时共享的运行总数中添加另一个线程、将数据从一个堆栈移动到堆到另一个堆栈等。

不过,更高效并不会使它更“正确”。当前线程通常在做一些对时间相当敏感的事情,并将工作交给池,以便它可以回到它主要关注的任何任务,而无需等待工作完成。

如果“currentThread”是主要的 GUI 线程,并且你正在假装一个需要 30 秒的打印假脱机作业,一个 ExecutorService 的实现会说“哦,好吧,这里只有一个作业,我会运行它在当前线程中”实际上是非常错误的,您的用户会让您知道他们的 30 秒挂断有多么错误!

于 2012-06-27T06:03:03.683 回答