【问题标题】:Java: ExecutorService less efficient than manual Thread executions?Java:ExecutorService 比手动线程执行效率低?
【发布时间】:2011-03-08 02:29:57
【问题描述】:

我有一个多线程应用程序。当使用 Thread.start() 手动启动线程时,每个并发线程恰好使用 25% 的 CPU(或恰好一个核心 - 这是在四核机器上)。所以如果我运行两个线程,CPU 使用率正好是 50%。

然而,当使用 ExecutorService 运行线程时,似乎有一个“幽灵”线程消耗 CPU 资源!一个线程使用 50% 而不是 25%,两个线程使用 75%,等等。

这可能是某种 Windows 任务管理器人工制品吗?

执行器服务代码是

ExecutorService executor = Executors.newFixedThreadPool(threadAmount);

for (int i = 1; i < 50; i++) {
    Runnable worker = new ActualThread(i);
    executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {

}
System.out.println("Finished all threads");

而 Thread.start() 代码是:

ActualThread one= new ActualThread(2,3);
ActualThread two= new ActualThread(3,4);
...

Thread threadOne = new Thread(one);
Thread threadTtwo = new Thread(two);
...

threadOne.start();
threadTwo.start();
...

【问题讨论】:

  • 第二个例子中等待线程完成的代码在哪里?

标签: java multithreading performance


【解决方案1】:

这是你的问题:

while (!executor.isTerminated()) {

}

您的“主要”方法使 CPU 无所事事。改用invokeAll(),你的线程会在没有忙等待的情况下阻塞。

final ExecutorService executor = Executors.newFixedThreadPool(threadAmount);
final List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();

for (int i = 1; i < 50; i++) {
    tasks.add(Executors.callable(new ActualThread(i)));
}
executor.invokeAll(tasks);
executor.shutdown();  // not really necessary if the executor goes out of scope.
System.out.println("Finished all threads");

由于invokeAll() 想要Callable 的集合,请注意使用辅助方法Executors.callable()。实际上,您也可以使用它来获取任务的 Futures 集合,如果任务实际上产生了您想要的输出,这将非常有用。

【讨论】:

  • +1,稍小的变化是使用awaitTermination
  • @Mark,是的,但是当invokeAll() 为您服务时,为什么还要手动杂技呢?这种模型也鼓励重用执行器,这通常是一件好事……无论如何,两者都行得通。
猜你喜欢
  • 1970-01-01
  • 2019-05-01
  • 2016-11-10
  • 2011-10-02
  • 2013-04-27
  • 2020-09-21
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多