我什么时候应该使用 Executor 而不是 ExecutorService

When should I use Executor over ExecutorService

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

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

  1. 我什么时候会使用 Executor 而不是 ExecutorService?我可以在任何地方使用 ExecutorService 吗?
  2. 有没有办法为执行者的执行添加显式 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();
    }
}

Q: When would be a scenario when I would use Executor over ExecutorService?

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

很少有您不需要以某种方式管理执行程序服务的情况,很少有您不需要管理该服务的应用程序。

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


Q: Can I use ExecutorService everywhere?

答:假设你实例化了ExecutorService的一个实例,是的。


Q: Is there a way to add an explicit shutdown for an Executor's execute or what is the general practice around it?

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

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

(当然...如果您知道它可能是 ExecutorService,那么您 可以 将其转换为 ExecutorService 然后呼叫 ExecutorService.shutdown().)

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

但是如果你使用ExecutorService.submit方法,你会得到每个任务的Future。您可能可以使用Future.cancel()从运行停止相应的任务,或者如果当前是运行.

则中断它。

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

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