問題
完了サービスを使用し、子スレッドを生成して ETL を実行しています。IDE でデバッグしてからすべてのプロセスを停止すると、CPU を殺してしまうゾンビ スレッドがまだたくさんあることに気付きます。これは、子スレッドを適切に終了していないためです。
最小の例
Future<Boolean> future = completionService.submit(conversionProcessor);
boolean isCompleted = false;
while (!isCompleted && !closed.get()) {
try {
isCompleted = future.get(CONSUMER_HEARTBEAT_INTERVAL,
TimeUnit.SECONDS); // Wait until heartbeat interval exceeds
if (isCompleted) {
// do some things here
future.cancel(true);
break;
}
} catch (TimeoutException e) {
// Used to keep consumer alive in the cluster
consumer.poll(Duration.ofSeconds(CONSUMER_HEARTBEAT_INTERVAL)); // does heart-beat
} catch (CancellationException e) {
future.cancel(true);
break;
} catch (InterruptedException e) {
future.cancel(true);
break;
} catch (WakeupException we) {
future.cancel(true);
break;
} catch (Exception e) {
future.cancel(true);
break;
}
考え
基本的に、私Callable<Boolean>
は完成サービスに提出します。
ExecutorCompletionService<Boolean> completionService = new ExecutorCompletionService<>(
Executors.newSingleThreadExecutor());
デバッガーを停止しても、このスレッドはおそらくまだ実行中です。この部分を追加したところfuture.cancel(true)
、子スレッドから継続的にアップロードされたファイルが停止したようですが、これらの Java プロセスがアクティビティ モニターで実行されています。
これをどう考えたらいいのかな?と思います。基になる ETL が完了したかどうか (true/false) を教えてくれる呼び出し可能オブジェクトが必要です
編集:future.cancelは実際にはかなり役に立っているようです..これは私が使いたいものですか?