【问题标题】:When should I use Executor over ExecutorService我什么时候应该使用 Executor 而不是 ExecutorService
【发布时间】:2022-01-01 06:23:19
【问题描述】:

我正在学习多线程,我遇到了this SO post

  • Executor 只是执行我们给它的东西。

  • ExecutorService 增加了启动、关闭以及等待和查看我们在 Executor(它扩展)之上提交以执行的作业状态的能力。

我仍在努力思考 Executor 和 ExecutorService 的使用。

  1. 什么情况下我会使用 Executor 而不是 ExecutorService?我可以在任何地方使用 ExecutorService 吗?
  2. 有没有办法为 Executor 的执行添加显式的 shutdown 或者围绕它的一般做法是什么?

我使用Executor 的以下代码不会终止。这是使用 Executor 的正确方法还是我在这里遗漏了什么?如何正确终止代码?我知道 Executor 没有shutdown。那么这个程序是否预计不会终止?

import java.util.concurrent.*;

public class A {
    public static void main(String[] args) {
        Executor executor = Executors.newFixedThreadPool(3);
        executor.execute(() ->
                System.out.println("Executor Class: " +
                        Thread.currentThread().getId() + ", Name: " +
                        Thread.currentThread().getName()));
    }
}

如果我用ExecutorService 替换上面的内容并添加shutdown,程序将正常终止。

import java.util.concurrent.*;

public class A {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        executor.submit(() ->
                System.out.println("ExecutorService Class: " +
                        Thread.currentThread().getId() + ", Name: " +
                        Thread.currentThread().getName()));
        executor.shutdown();
    }
}

【问题讨论】:

  • ExecutorService 接口扩展了Executor 接口。 ExecutorService 提供了一些额外的协调方法,例如 shutdown 和 awaitTermination。因此,它基于您的用例。作为一个好的做法,您可以随时使用ExecutorService

标签: java multithreading executorservice


【解决方案1】:

问:什么情况下我会使用 Executor 而不是 ExecutorService?

答:当您知道您永远不会使用任何ExecutorService 方法时。

在少数情况下您不需要以某种方式管理执行器服务,在少数应用程序中您不需要管理该服务。

(假设...如果您正在创建自己的任务执行机制而不涉及在本地线程中运行任务,那么ExecutorService 的管理功能可能不合适。)


问:我可以在任何地方使用ExecutorService吗?

答:假设您实例化了ExecutorService 的实例,是的。


问:有没有办法为 Executor 的执行添加显式关闭或围绕它的一般做法是什么?

如果你问是否可以关闭整个Executor,没有没有办法。

Executor 服务是一个接口。一般来说,它可以以根本无法关闭的方式实现。但无论哪种方式,如果你不知道执行器是如何实现的,那么你就不知道如何告诉它自己关闭。

(当然...如果您知道它可能是ExecutorService,那么您可以将其类型转换为ExecutorService,然后调用ExecutorService.shutdown()。)

另一方面,如果你问是否可以取消Executor.execute提交的特定任务,答案也是否定的。

但如果您使用ExecutorService.submit 方法,您将获得每个任务的Future。您也许可以使用Future.cancel() 来停止相应任务的运行,或者如果它当前正在运行则中断它。

【讨论】:

  • 感谢您的澄清!那么我的第一个程序预计不会终止吗?
  • 因为默认线程工厂不创建守护线程......是的。在这两种情况下,main 将终止,但 JVM 将继续运行。在第二种情况下,当所有任务都完成后,JVM 将退出。
【解决方案2】:

您应该使用ExecutorService 接口来管理执行器服务。该接口通常由创建或拥有执行器服务的对象使用。

只需要使用在其他地方管理的执行器执行内容的对象或方法应该采用Executor 类型的参数。您可以传递ExecutorService 的实例,因为它实现了Executor

【讨论】:

    猜你喜欢
    • 2011-06-22
    • 2016-08-09
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    相关资源
    最近更新 更多