ゼロループを持つ長時間実行する関数を時間制限する必要があります。私はその機能をCallable
で実行し、将来はget
とタイムアウト値で呼び出します。 AFAIU、future.cancel(true)
は、関数スレッドの割り込みフラグを設定します。しかし、私がチェックしてThread.isInterrupted()を処理しない限り、longRunningFunction()
私のコードは終了しなければならず、shutdownNow()
の後でも関数は終了しません。Javaのゼロループスレッドの割り込みを確認します。
longRunningFunction()
で割り込みが発生したかどうかを確認するにはどうすればよいですか?チェックは即座に行う必要があります。つまり、チェックが特定のポイントに置かれ、それらのポイントがヒットするまで、スレッドは割り込みを処理しません。- タイムリミット機能には他に優雅な方法がありますか?
- なぜ私はエクゼキュータプール内のすべてのスレッドを強制終了できませんか? JavaDocs for ExecutorServiceによれば、スレッドは割り込みを処理して終了するまで、プールは決して終了しません。
public class Test {
public void longRunningFunction() {
/*
Long running code without loop
*/
}
public Void call() {
try {
longRunningFunction()
} catch (InterruptedException exception) {
logger.error("{} Error : {}", TAG, exception.getStackTrace().join("\n"))
} catch (Exception exception) {
logger.error("[call]{} Error : {}", TAG, exception.getStackTrace().join("\n"))
}
}
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor()
Future<Void> future = executor.submit(new Test())
int timeoutSeconds = 5
println "Setting timeout to " + timeoutSeconds
try {
future.get(timeoutSeconds, TimeUnit.SECONDS)
} catch (TimeoutException e) {
future.cancel(true)
logger.error("Could not finish processing within {} seconds", timeoutSeconds)
} finally {
executor.shutdownNow()
executor.awaitTermination(3, TimeUnit.SECONDS)
logger.error("Shutting down")
}
}
}
編集 重複をマークするためにリンクの質問は質問で述べたように知られた事実である、共有変数が進むべき道であることを示唆しています。問題は、そのブール値フラグをどの程度シームレスにチェックするかです。つまり、Thread.isInterrupted
です。
'longRunningFunction'にループがない場合でも、この関数内に中間ステップがないため、割り込みフラグをチェックすることはできません。 – freedev
[Javaでスレッドをどのように殺すのですか?]の複製がありますか?(http://stackoverflow.com/questions/671049/how-do-you-kill-a-thread-in-java) – freedev
上記のリンクから、共有変数(ここでは 'isInterrupted'フラグ)が使用されます。それは知られている事実です。疑問は、ブール変数をシームレスにチェックする方法です。 – ankshah