0

以下のように、接続タスクにExecutorServiceを使用しています。

ExecutorService executor = Executors.newSingleThreadExecutor();
Future<ApplicationConnection> future = (Future<ApplicationConnection>) executor.submit(new ConnectThread(crf, connoptions));
connection = future.get(300000, TimeUnit.SECONDS);
executor.shutdownNow();

call()メソッドは、メソッド (独自の.connect()API) を呼び出します。この接続メソッドは、さまざまなスレッドプールなどを生成します。私の懸念は、未来がタイムアウトしてエグゼキューターを強制終了した場合、.connect()将来メソッドを呼び出すことによって既に生成されている可能性のあるスレッドも終了するのでしょうか? スレッドを強制終了すると子スレッドも強制終了されることはわかっていますが、これは同じロジックに従っていますか?

4

2 に答える 2

2

あなたの仮定は正しいですFuture。タイムアウトした場合、ハングしているスレッドがいくつか残ります。さらに悪いことに、shutdownNow()プール スレッドもシャットダウンしません (独自の API スレッドは言うまでもありません)。新しい仕事の受け入れをやめるだけです。ExecutorService実行中のすべてのタスクが終了すると、スレッド プールはすべてのスレッドを終了します。

あなたにできることは、未来をキャンセルして中断することです。InterruptedExceptionあなたの未来の中の最初のハンドル:

class ConnectThread implements Callbale<ApplicationConnection> {

    public ApplicationConnection call() {
        try {
            return prioprietaryApi.connect();
        } catch(InterruptedException e) {
            prioprietaryApi.cleanUp();
            throw e;
        }
    }

}

今すぐ実行してください:

future.cancel(true);

ただし、独自の API は処理できない可能性がありますInterruptedException( .connect()cleanUp()

このような状況では、ただ... 忘れてください。最終的にはそれFuture自体が終了してクリーンアップされ、それを待つ必要がなくなったという事実は無視されます。もちろん、これはさまざまなスケーラビリティの問題につながる可能性があります。

ところで、達成したい唯一のことが特定のメソッド実行の最大時間を制限することである場合は、TimeLimiterから検討してください。

于 2012-12-17T18:49:23.090 に答える
1

javadocに従って

アクティブに実行中のすべてのタスクの停止を試み、待機中のタスクの処理を停止し、実行を待機していたタスクのリストを返します。アクティブに実行中のタスクの処理を停止するための最善の努力以外の保証はありません。たとえば、典型的な実装は Thread.interrupt() によってキャンセルされるため、割り込みに応答しないタスクは決して終了しない可能性があります。

于 2012-12-17T18:46:03.510 に答える