2

I want to start a thread and cancel it if it doesn't finish within 5 seconds:

private final class HelloWorker implements Callable<String> {
    public String call() throws Exception {
        while(true) {
            if (Thread.isInterrupted()) {
                return null;
            }
        }
        return performExpensiveComputation();
    }

    private String performExpensiveComputation() {
        // some blocking expensive computation that may or may not take a very long time
    }
}

private ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
Future<String> future = executorService.submit(new HelloWorker());

try {  
    String s = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
    future.cancel(true);

    System.out.println("cancelled: " + future.isCancelled() + "done: " + future.isDone());

    executorService.shutdown();

    try {
        System.out.println("try to terminate: " + executorService.awaitTermination(60, TimeUnit.SECONDS));
    } catch (Exception ex) {
        // ignore
    }
}

However it looks like the awaitTermination returns false. Is there a way for me to check why an ExecutorService won't terminate? Can I figure out what threads are still running?

4

2 に答える 2

4

残りのプロセスの安定性を損なうことなく、実行中のスレッドを安全に停止する方法はありません。これが、Thread#stopがずっと前に廃止された理由であり、エグゼキュータ サービスがソフトで協調Thread#interrupt的なメカニズムのみを使用する理由です。

スレッドは、割り込みが要求されたかどうかを積極的にチェックし、終了する前に適切なクリーンアップを実行する必要があります。あるいは、スレッドはいくつかの割り込み可能な JDK メソッドを呼び出します。これは をスローInterruptedExceptionし、トレッドはそれを適切に受け入れて終了します。

于 2013-12-19T21:30:04.630 に答える