Przy zastosowaniu ExecutorService
i Future
obiektów (przy składaniu Runnable
zadania), jeśli mogę określić wartość limitu czasu dla funkcji uzyskać Future, czy podstawowa wątek zginąć gdy TimeoutException
zostaje wyrzucony?robi Future Timeout zabić wykonanie wątku
Odpowiedz
Nie dotyczy. Dlaczego miałby to robić? Chyba że mu to powiesz.
Jest to bardzo ważna kwestia, na przykład w przypadku opcji Wysyłania. Jeśli czekasz na wynik, powiedzmy 20 sekund i nie dostałeś tego, to nie jesteś już zainteresowany rezultatem. W tym czasie należy w ogóle anulować zadanie.
coś takiego:
Future<?> future = service.submit(new MyCallable());
try {
future.get(100, TimeUnit.MILLISECONDS);
} catch (Exception e){
e.printStackTrace();
future.cancel(true); //this method will stop the running underlying task
}
Nie, nie robi. Poza tym nie ma nawet próby przerwania zadania. Przede wszystkim Future.get z limitem czasu nie mówi tak. Po drugie, spróbuj mój test, aby zobaczyć, jak zachowuje się
ExecutorService ex = Executors.newSingleThreadExecutor();
Future<?> f = ex.submit(new Runnable() {
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("finished");
}
});
f.get(1, TimeUnit.SECONDS);
w 1 sekundę drukuje
Exception in thread "main" java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:228)
at java.util.concurrent.FutureTask.get(FutureTask.java:91)
at Test1.main(Test1.java:23)
po kolejnej 1 sekundach successfullt zadanie zakończy
finished
... Dobrze, że * * 'Future' szczególności realizacja nie. Ponieważ jest to interfejs, nie można tworzyć ogólnych stwierdzeń na temat wszystkich "Przyszłości". –
Future.get (long timeout, jednostka TimeUnit) nie mówi, że spróbuje zatrzymać zadanie. Poza tym, czy istnieje wiele sposobów na zatrzymanie działającego wątku? –
Dobra odpowiedź, wycofuję skargę! –
Wydaje się, że trzeba zabij, anuluj lub zamknij zadanie jawnie
Tylko komentarz: 'future.cancel (true);' does ** not ** zatrzymuje uruchomione zadanie podstawowe, po prostu ustawia przerwaną flagę na true dla działającego wątku. To jest twój kod, który jest odpowiedzialny za sprawdzenie tej flagi i wyrzucenie InterruptedException, jeśli to prawda. –
@ ThiagoKronig, jesteś pewien? z [documentation] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel (boolean)), jeśli podasz wartość true, wątek powinien zostać przerwany a próba powinna zawieść. – Dirk
@Dirk, z dokumentacji, którą mamy: _Jeśli zadanie już się rozpoczęło, parametr mayInterruptIfRunning określa, czy wątek wykonujący to zadanie_ ** powinien zostać przerwany, próbując zatrzymać zadanie **. _Interruption_ tutaj oznacza, że ustawi on na prawdziwą zmienną flagę tego wątku. Działający kod musi przetestować, czy ten warunek nie może się zatrzymać. Kod musi się zatrzymać. –