簡體   English   中英

當我們允許注入它時,如何管理 ExecutorService 的關閉?

[英]How to manage shutdown of ExecutorService when we allow to inject it?

假設我正在編寫一個服務,它需要一些執行程序服務/單獨的線程。 我提供了使用工廠方法的能力,而不用擔心執行程序服務,但仍然希望允許傳遞現有的執行程序服務(依賴注入)。

我如何管理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())
  • 如果執行器是外部管理的(注入),我們不應該關閉它

我們可以創建一些屬性來說明 executor 是由我們的類創建還是被注入,然后在 finalize/@PreDestroy/shutdown 鈎子上我們可以關閉它,但這對我來說並不優雅。

也許我們應該完全放棄工廠方法,並始終需要將執行器生命周期管理注入客戶端?

您可以從默認工廠創建匿名子內部類的實例,如下所示。 該類將定義由您的 DI 容器調用的 close/@PreDestroy 方法。 例如

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();
            }
        };
    }
}

我會說這個解決方案完全取決於你。 第三方庫如 spring 廣泛使用專用屬性來了解誰應該根據其創建者發布特定資源。 mongoInstanceCreatedSimpleMongoDbFactorylocalServerSimpleHttpServerJaxWsServiceExporter等,但他們這樣做是因為這些類僅外部使用創建的。 如果您的類僅在您的應用程序代碼中使用,那么您可以注入executorService並且不關心它的釋放,或者在使用它的類中創建和釋放它。 這種選擇取決於你的類/應用程序設計(做你的類工作,任何executorService ,是否executorService共享以及其他類使用,等等)。 否則,除了專用標志之外,我看不到其他選項。

更“優雅”的解決方案是擴展您的 ExecutorService 並在其中覆蓋關閉方法(無論您選擇哪種方式)。 在注入的情況下,您將返回該擴展類型,並且它將擁有自己的關閉邏輯。 在工廠的情況下 - 你仍然有原始邏輯。

經過一番思考,我得出了一些結論:

  • 如果它被注入,不要考慮關閉它 - 其他人創建了它,其他人將管理它的生命周期
  • 可以注入執行器工廠而不是執行器,然后我們使用工廠創建實例並在我們管理生命周期時自行管理關閉它(在這種情況下,其他用戶的響應適用)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM