java - 当我们允许注入(inject)时如何管理 ExecutorService 的关闭?

标签 java dependency-injection resources resource-cleanup

假设我正在编写一个服务,它需要一些执行程序服务/单独的线程。 我提供了使用工厂方法的能力,不用担心执行器服务,但仍然希望允许传递现有的执行器服务(依赖注入(inject))。

我如何管理 executorService.shutdown()

示例代码:

public class ThingsScheduler {

    private final ExecutorService executorService;

    public ThingsScheduler(ExecutorService executorService) {
        this.executorService = executorService;
    }

    public static ThingsScheduler createDefaultSingleThreaded() {
        return new ThingsScheduler(Executors.newSingleThreadExecutor());
    }

    public scheduleThing() {
        executorService.submit(new SomeTask());
    }

    // implement Closeable?
    // @PreDestory?
    // .shutdown() + JavaDoc?
}

有几个问题

  • 我们应该有能力关闭内部创建的执行器,或者在最好的情况下自动处理它(Spring @PreDestory,或者在最坏的情况下 finalize())
  • 如果执行器是外部管理的(注入(inject)的),我们宁愿不关闭它

我们可以创建一些属性来说明执行器是由我们的类创建的还是被注入(inject)的,然后在 finalize/@PreDestroy/shutdown Hook 上我们可以关闭它,但对我来说感觉并不优雅。

也许我们应该完全放弃工厂方法,并始终要求注入(inject)将执行程序生命周期管理推送给客户端?

最佳答案

您可以从您的默认工厂创建一个匿名子内部类的实例,如下所示。该类将定义 close/@PreDestroy 方法,您的 DI 容器将调用该方法。 例如

public class ThingsScheduler {
    final ExecutorService executorService;

    public ThingsScheduler(ExecutorService executorService) {
        this.executorService = executorService;
    }

    /**
     * assuming you are using this method as factory method to make the returned
     * bean as managed by your DI container
     */
    public static ThingsScheduler createDefaultSingleThreaded() {
        return new ThingsScheduler(Executors.newSingleThreadExecutor()) {
            @PreDestroy
            public void close() {
                System.out.println("closing the bean");
                executorService.shutdown();
            }
        };
    }
}

关于java - 当我们允许注入(inject)时如何管理 ExecutorService 的关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47260691/

相关文章:

java - spring中如何在mongoDB中查询和过滤

java - 改变注入(inject)对象的状态是不好的做法吗?

c# - C# 中的单元测试工厂类

java - 在两个 bean 中注入(inject) spring bean-实现相同的接口(interface)

.net - 如何以编程方式枚举 resx 文件中的资源?

c++ - vs10 C++ $(MyLibrary) 与 %(MyLibrary)

java - 通过 CDI 注入(inject)记录器,一种反模式?

java - 使用 JPA 和 MySQL 检查用户是否喜欢该帖子的最佳方法是什么?

java - 是否存在带有类型参数的泛型(generics with generics)?

c# - 使用 InvariantCulture 或 CurrentCulture 格式化异常消息?