Frage

In dem folgenden Code, ich bin Fang ein Timeout nach 100 Sekunden, wie beabsichtigt. An dieser Stelle möchte ich den Code erwarten von Haupt- und das Programm zu beenden zu beenden, aber es hält Druck auf die Konsole. Wie erhalte ich die Aufgabe, nach Zeit zu stoppen Ausführung?

private static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool();

private static <T> T timedCall(Callable<T> c, long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
    FutureTask<T> task = new FutureTask<T>(c);
    THREAD_POOL.execute(task);
    return task.get(timeout, timeUnit);
}


public static void main(String[] args) {

    try {
        int returnCode = timedCall(new Callable<Integer>() {
            public Integer call() throws Exception {
                for (int i=0; i < 1000000; i++) {
                    System.out.println(new java.util.Date());
                    Thread.sleep(1000);
                }
                return 0;
            }
        }, 100, TimeUnit.SECONDS);
    } catch (Exception e) {
        e.printStackTrace();
        return;
    }


}
War es hilfreich?

Lösung

Sie müssen Ihre Aufgabe Timeout abbrechen (und unterbrechen ihr Gewinde). Das ist, was cancel(true) Methode ist für. :

private static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool();

private static <T> T timedCall(FutureTask<T> task, long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
    THREAD_POOL.execute(task);
    return task.get(timeout, timeUnit);
}


public static void main(String[] args) {
        try {
            FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() {
                public Integer call() throws Exception {
                        for (int i=0; i < 1000000; i++) {
                                if (Thread.interrupted()) return 1;
                                System.out.println(new java.util.Date());
                                Thread.sleep(1000);
                        }
                        return 0;
                }
            });
            int returnCode = timedCall(task, 100, TimeUnit.SECONDS);
        } catch (Exception e) {
                e.printStackTrace();
                task.cancel(true);
        }
        return;
}

Andere Tipps

Ihr Callable muss in der Lage sein schnell zu stoppen, wenn nötig.

Ihr Code:

public Integer call() throws Exception {
    for (int i=0; i < 1000000 && !task.cancelled(); i++) {
        System.out.println(new java.util.Date());
        Thread.sleep(1000); // throws InterruptedException when thread is interrupted
    }
    return 0;
}

Ist bereits in der Lage zu tun, dass dank Thread.sleep() aufrufen. Punkt ist, dass futureTask.cancel(true) wird anderen Thread unterbrechen, und Ihr Code muss auf diese Unterbrechung reagieren. Thread.sleep() tut das. Wenn Sie nicht Thread.sleep() oder anderen unterbrechbare Sperrcode verwendet haben, würden Sie haben Thread.currentThread().isInterrupted() selbst zu überprüfen, und so bald wie möglich (zum Beispiel durch das Werfen new InterruptedException()) beendet, wenn Sie dies um wahr zu sein zu finden.

Sie müssen futureTask.cancel(true); von Ihrem Exception-Handler aufrufen Thread zu löschen und zu unterbrechen, die Ihre Aufgabe ausgeführt wird.

Mein Rat über Unterbrechungsmechanismus zu lernen, ist (dies ist großer Artikel: Der Umgang mit InterruptedException ), und es verwenden.

Wenn Sie die Timeout gefangen, müssen Sie die Abbrechen (true) Methode Ihrer Aufgabe nennen ...

oder Ihre ExecutorService heruntergefahren durch den Aufruf shutdownNow () ...

oder die VM beenden, indem System.exit Aufruf (0)

Je nach Bedarf

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top