2009-11-02 16 views
25

Mam następujący problem i chciałbym się dowiedzieć, co dokładnie się dzieje. Używam Java ScheduledExecutorService do uruchamiania zadania co pięć minut. Pracuje bardzo dobrze. Executory całkowicie zmieniły sposób programowania wątków w Javie.Nieobsługiwane wyjątki z wykonawcami zaplanowanymi w języku Java

Teraz przeglądałem dokumentację Java, aby uzyskać informacje o tym, jak zachowałoby się, gdyby zaplanowane zadanie zakończyło się niepowodzeniem z nieobsługiwanym wyjątkiem, ale nie mogło znaleźć nic.

Czy następne zaplanowane zadanie nadal będzie uruchamiane? Jeśli istnieje nieobsługiwany wyjątek, zaplanowany executor zatrzymuje zadanie planowania? Czy ktoś może wskazać informacje dotyczące tego prostego problemu?

Wielkie dzięki.

Odpowiedz

24

Javadoc zarówno z scheduleAtFixedRate, jak i scheduleWithFixedDelay mówi "Jeśli jakakolwiek realizacja zadania napotka wyjątek, kolejne egzekucje zostaną wyłączone." Nie wydaje mi się, żeby było to dokładnie krystalicznie czyste, ale wydaje się, że jeśli twoja metoda run rzuca jakiś wyjątek, to planista skutecznie upuści to zadanie. Nie powinno to wpłynąć na żadne inne zadania wykonywane za pośrednictwem tego programu planującego. Nie powinno być trudno przetestować, co faktycznie robi ...

Anulowanie zadania niekoniecznie musi być złe. Jeśli metoda run wyśle ​​RuntimeException, prawdopodobnie ma gdzieś błąd, a stan systemu jest nieznany. Ale przynajmniej zaleciłabym przechwycenie RuntimeException w metodzie run i rejestrowanie pełnego śledzenia stosu w SEVERE. Możesz następnie ponownie rzucić, aby anulować zadanie, w zależności od okoliczności. Ale tak czy inaczej będziesz potrzebować rejestrowania, aby mieć szansę na wypracowanie tego, co poszło nie tak.

+0

dziękuję za odpowiedzi. Nie widziałem tego w API Doc. –

+5

Szybkie przeglądanie źródła dla ThreadPoolExecutor (na którym zaimplementowano STPE) sugeruje, że RuntimeExceptions zostaną starannie przechwycone i zgłoszone za pomocą ScheduledFuture, ale także spowodują zakończenie wątku roboczego. TPE zauważy to zakończenie wątku roboczego i w razie potrzeby zakręci nowy zamiennik. Zobacz: runWorker() i processWorkerExit() w java.util.concurrent.ThreadPoolExecutor w źródłach JDK lub w witrynie Douga Lea. – andersoj

11

Jeśli używasz scheduleAtFixedRate() lub scheduleAtFixedDelay(), a Twoje zadanie zostanie wycofane z wyjątkiem, zadanie to nie zostanie przełożone. Jednak inne niezależne zadania powinny być nadal wykonywane zgodnie z oczekiwaniami. (Patrz API Docs). Jeśli masz na to wpływ, możesz pobrać przechwyconą wartość ScheduledFuture i wywołać metodę get(). Jeśli podstawowe zadanie rzuci wyjątek, zostanie ono wyrzucone z metody get(), opakowanej w ExecutionException.

+0

Wielkie dzięki za odpowiedź. +1. Szkoda, że ​​nie mogę zaakceptować dwóch odpowiedzi jako "odpowiedzi". Dzięki jeszcze raz. –

+0

Hej, stary, Lachlan pobił mnie na pięści ... zasady to zasady. ;-) – andersoj

+0

Dziwne ... moje kolejne zadanie też się zatrzymało. –

-3

Wygląda na to, że interfejs API nie definiuje żadnego określonego mechanizmu obsługi wyjątków. To znaczy. uncaught wyjątek po prostu przechodzi przez ramki wątków i ostatecznie jest logowany do stderr.

widzę, że można wykorzystać następujące strategie manipulacji wyjątek:

+0

Nie sądzę, że te wyjątki są rejestrowane. –

1

Ten człowiek miał ten sam problem.

http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/

Jego rozwiązanie jest złapać Exception wewnątrz runnable i ponownie rzucić RuntimeException:

try { 
     theRunnable.run(); 
    } catch (Exception e) { 
     // LOG IT HERE!!! 
     System.err.println("error in executing: " + theRunnable + ". It will no longer be run!"); 
     e.printStackTrace(); 

     // and re throw it so that the Executor also gets this error so that it can do what it would 
     // usually do 
     throw new RuntimeException(e); 
} 
Powiązane problemy