使用ExecutorService有什么好处?
什么是使用的优势ExecutorService
在正在运行的线程传递一个Runnable
到Thread
构造函数?
ExecutorService
抽象出许多与较低级别抽象(如原始Thread
相关的复杂性。 它为成功或突然终止任务(表示为Runnable
或Callable
)提供了安全启动,关闭,提交,执行和阻止的机制。
从JCiP,第6.2节,直接从马的嘴巴:
Executor
可能是一个简单的接口,但它构成了异步任务执行的灵活和强大框架的基础,该框架支持各种任务执行策略。 它提供了将任务提交与任务执行分离的标准方法,将任务描述为Runnable
。 Executor
实现还提供了生命周期支持和钩子,用于添加统计信息收集,应用程序管理和监视。 ...使用Executor
通常是在应用程序中实现生产者 - 消费者设计的最简单途径。 juconcurrent
框架不是花时间实现并行性的底层基础架构(通常不正确,而且花费很大的精力), juconcurrent
让您专注于构建任务,依赖关系和潜在的并行性。 对于大量的并发应用程序,可以直接识别和利用任务边界并利用juc
,从而使您能够专注于可能需要更专业解决方案的真正并发挑战的小部分子集。
此外,尽管具有样板文件的外观和感觉,总结并发实用程序的Oracle API页面包含了一些非常可靠的使用它们的参数,并非最不重要的:
开发人员可能已经了解了标准库类,因此不需要学习API和特定并发组件的行为。 此外,当并行应用程序构建在可靠,经过充分测试的组件上时,它们的调试要简单得多。
关于SO的这个问题问到一本好书,JCiP立即回答了这个问题。 如果你还没有,给自己一个副本。 在那里提出的综合并发方法远远超出了这个问题,并且从长远来看将为您节省很多心痛。
我看到的一个优点是管理/调度多个线程。 使用ExecutorService,您不必编写自己的线程管理器,它可能会受到bug的困扰。 如果你的程序需要一次运行多个线程,这是特别有用的。 例如,你想要一次执行两个线程,你可以很容易地做到这一点:
ExecutorService exec = Executors.newFixedThreadPool(2);
exec.execute(new Runnable() {
public void run() {
System.out.println("Hello world");
}
});
exec.shutdown();
这个例子可能是微不足道的,但试图认为“hello world”这一行由一个繁重的操作组成,并且您希望该操作一次在多个线程中运行,以提高程序的性能。 这只是一个例子,还有很多情况下您想要安排或运行多个线程并使用ExecutorService作为您的线程管理器。
为了运行单个线程,我没有看到使用ExecutorService的明显优势。
以下是一些好处: