2013-04-26 9 views

Odpowiedz

38

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 
    } 
+13

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. –

+0

@ 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

+7

@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ć. –

14

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 
+1

... 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". –

+6

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? –

+0

Dobra odpowiedź, wycofuję skargę! –