使用执行器服务有哪些优势?

使用将 a 传递到构造函数中的超运行线程有什么好处?ExecutorServiceRunnableThread


答案 1

ExecutorService抽象出许多与低级抽象相关的复杂性,如原始。它提供了在任务成功或突然终止时安全启动、关闭、提交、执行和阻止任务(表示为 或 )的机制。ThreadRunnableCallable

来自JCiP,第6.2节,直接从马的嘴里:

Executor可能是一个简单的接口,但它构成了一个灵活而强大的异步任务执行框架的基础,该框架支持各种任务执行策略。它提供了一种将任务提交与任务执行分离的标准方法,将任务描述为 。这些实现还提供了生命周期支持和挂钩,用于添加统计信息收集、应用程序管理和监视。...使用执行器通常是在应用程序中实现生产者-使用者设计的最简单途径。RunnableExecutor

该框架不是花时间实现(通常是错误的,并且花费了大量精力)底层基础架构以实现并行性,而是允许您将重点放在构建任务,依赖关系,潜在的并行性上。对于大量的并发应用程序,识别和利用任务边界并利用 是很简单的,这使您可以专注于真正的并发挑战的较小子集,这些挑战可能需要更专业的解决方案。j.u.concurrentj.u.c

此外,尽管有样板外观和感觉,但总结并发实用程序的Oracle API页面包含了一些使用它们的真正可靠的论据,尤其是:

开发人员可能已经了解了标准库类,因此无需学习即席并发组件的 API 和行为。此外,当并发应用程序构建在可靠、经过良好测试的组件上时,调试起来要简单得多。

SO的这个问题问的是一本好书,直接的答案是JCiP。如果您还没有,请给自己买一份副本。这里介绍的并发性综合方法远远超出了这个问题,从长远来看,这将为您节省很多心痛。


答案 2

我看到的一个优势是管理/调度多个线程。使用ExecutorService,您不必编写自己的线程管理器,这可能会受到错误的困扰。如果您的程序需要同时运行多个线程,这尤其有用。例如,您希望一次执行两个线程,您可以轻松地执行以下操作:

ExecutorService exec = Executors.newFixedThreadPool(2);

exec.execute(new Runnable() {
  public void run() {
    System.out.println("Hello world");
  }
});

exec.shutdown();

这个例子可能微不足道,但试着认为“hello world”行由一个繁重的操作组成,并且您希望该操作一次在多个线程中运行,以提高程序的性能。这只是一个例子,仍然有很多情况下,您希望计划或运行多个线程并使用ExecuterService作为线程管理器。

对于运行单个线程,我没有看到使用ExecutorService的任何明显优势。


推荐