web-dev-qa-db-ja.com

ExecutorServiceインターフェースがAutoCloseableを実装しないのはなぜですか?

スレッドエグゼキュータでshutdown()を呼び出さないと、アプリケーションが終了することはありません。

ExecutorServiceをシャットダウンするためのベストプラクティスは次のとおりです。

ExecutorService service = null;
try {
  service = Executors.newSingleThreadExecutor();
  // add tasks to thread executor
  …
} finally {
  if (service != null) service.shutdown();
}

Javaはtry-with-resourcesの概念を知っているので、これができたらいいのではないでしょうか。

try (service = Executors.newSingleThreadExecutor())
{
  // add tasks to thread executor
  …
} 
27
Adrian Krebs

その ExecutorService には、実際には2つのシャットダウン関連のメソッドがあります。サービスをシャットダウンする両方の方法が理にかなっているという単純な事実に基づいています。

したがって、サービスをどのように自動クローズしますか?すべての人に役立つ一貫した方法で?!

したがって、私の目には合理的な説明があります。ExecutorServiceには、「閉じる」ような操作が1つもないため、ExecutorServiceをAutoClosableにすることはできません。でも2つ!

そして、そのような自動クローズサービスをうまく利用できると思うなら、「委任」を使用して独自の実装を作成するのは5分です。または、おそらく10分です。これは、クローズ操作としてshutdown()を呼び出す1つのバージョンを作成するためです。代わりにshutdownNow()を実行するもの。

19
GhostCat

これは平凡な回避策です

ExecutorService service = Executors.newSingleThreadExecutor();
try (Closeable close = service::shutdown) {

}

または、チェックされた例外が気になる場合は、次のように記述できます。

interface MyCloseable extends AutoCloseable {
    void close();
}

その後

ExecutorService service = Executors.newSingleThreadExecutor();
try (MyCloseable close = service::shutdown) {

}

もちろん、割り当てとtryステートメントの間に何かを入れたり、serviceステートメントの後にtryローカル変数を使用したりしないでください。

警告がある場合は、代わりにfinallyを使用してください。

13
Lukas Eder

AutoCloseableがエグゼキュータにとってどこに役立つのかわかりません。 try-with-resourcesは、メソッドのスコープ内で初期化、使用、および解放できるもの用です。これは、ファイル、ネットワーク接続、jdbcリソースなど、ファイルがすばやく開かれ、使用され、クリーンアップされる場合に最適です。ただし、エグゼキュータ、特にスレッドプールは、おそらくアプリケーションの存続期間中、長期間利用できるようにしたいものであり、DIフレームワークが認識しているメソッドを持つことができるシングルトンサービスなどに注入される傾向があります。アプリケーションのシャットダウンを呼び出して、エグゼキュータをクリーンアップします。この使用パターンは、try-with-resourcesがなくても正常に機能します。

また、try-with-resourcesの背後にある大きな動機は、例外がマスクされないようにすることです。これはエグゼキュータではそれほど考慮されません。すべての例外スローはエグゼキュータに送信されたタスクで発生します。例外マスキングは問題ではありません。

0
Nathan Hughes