2013-09-10 7 views
27

Uczę się używać exectorServices do gromadzenia threads i wysyłania zadań. Mam prosty program poniżejRóżnica między executor.submit i executor.execute w tym kodzie w Javie?

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 


class Processor implements Runnable { 

    private int id; 

    public Processor(int id) { 
     this.id = id; 
    } 

    public void run() { 
     System.out.println("Starting: " + id); 

     try { 
      Thread.sleep(5000); 
     } catch (InterruptedException e) { 
      System.out.println("sorry, being interupted, good bye!"); 
      System.out.println("Interrupted "+Thread.currentThread().getName()); 
      e.printStackTrace();  
     } 

     System.out.println("Completed: " + id); 
    } 
} 


public class ExecutorExample { 

    public static void main(String[] args) { 
     Boolean isCompleted=false; 

     ExecutorService executor = Executors.newFixedThreadPool(2); 

     for(int i=0; i<5; i++) { 
      executor.execute(new Processor(i)); 
     } 

     //executor does not accept any more tasks but the submitted tasks continue 
     executor.shutdown(); 

     System.out.println("All tasks submitted."); 

     try { 
      //wait for the exectutor to terminate normally, which will return true 
      //if timeout happens, returns false, but this does NOT interrupt the threads 
      isCompleted=executor.awaitTermination(100, TimeUnit.SECONDS); 
      //this will interrupt thread it manages. catch the interrupted exception in the threads 
      //If not, threads will run forever and executor will never be able to shutdown. 
      executor.shutdownNow(); 
     } catch (InterruptedException e) { 
     } 

     if (isCompleted){ 
     System.out.println("All tasks completed."); 
     } 
     else { 
      System.out.println("Timeout "+Thread.currentThread().getName()); 
     } 
    } 
     } 

To nie robi nic nadzwyczajnego, ale tworzy dwa threads i przedkłada 5 Zadania w sumie. Po wykonaniu każdego z nich thread zajmuje następną, W powyższym kodzie używam executor.submit. Zmieniłem także na executor.execute. Ale nie widzę żadnej różnicy w wynikach. Czym różnią się metody submit and execute? To co API mówi

Sposób przedstawienia rozciąga metoda baza Executor.execute (java.lang.Runnable) poprzez tworzenie i powrocie do przyszłości, które mogą być wykorzystane, aby anulować wykonanie i/lub poczekać na zakończenie. Metody invokeAny i invokeAll wykonują najczęściej używane formy masowego wykonywania, wykonując zbiór zadań, a następnie czekając na ukończenie co najmniej jednego lub wszystkich. (Klasa ExecutorCompletionService może być używana do pisania dostosowanych wariantów tych metod.)

Ale nie jest dla mnie jasne, co to dokładnie oznacza? Dzięki

+0

użyteczne pytanie. Warto umieścić go tutaj. – MKod

Odpowiedz

29

Jak widać z JavaDoc execute(Runnable) nic nie zwraca.

Jednak submit(Callable<T>) zwraca Future przedmiot, który pozwala sposób, aby programowo przerwać nić później, a także uzyskać T który jest zwracany, gdy Callable ukończone,. Zobacz JavaDoc of Future więcej szczegółów

Future<?> future = executor.submit(longRunningJob); 
... 
//long running job is taking too long 
future.cancel(true); 

Ponadto jeśli future.get() == null i nie rzucać żadnych wyjątków następnie Runnable wykonana pomyślnie

30

Różnica polega na tym, że po prostu zaczyna execute zadanie bez dalszej zwłoki, natomiast submit zwraca Future obiekt do zarządzania zadanie. Można zrobić następujące rzeczy z przedmiotem Future:

  • Anuluj zadanie przedwcześnie, metodą cancel.
  • Poczekaj na zakończenie zadania, używając get.

Interfejs Future jest bardziej przydatny, jeśli użytkownik przesyła do puli zestaw Callable. Zwracana wartość metody call zostanie zwrócona po wywołaniu Future.get. Jeśli nie zachowujesz odniesienia do Future, nie ma różnicy.

3

Zatwierdź - Zwraca Future obiekt, który może być użyty do sprawdzenia wyniku złożonego zadania. Może być użyty do anulowania lub sprawdzenia isDone itp.

Execute - nic nie zwraca.

5

execute: Użyj go do ognia i zapomnieć połączeń

submit: Użyj go, aby sprawdzić wynik wywołania metody i podjąć odpowiednie działania na Future sprzeciwił zwrócony przez wywołanie

zasadnicza różnica: Exception obsługi

submit() ukrywa niezarządzane Exception w ramach samego.

execute() wyrzuca niezatłoczone Exception.

rozwiązanie dla obsługi wyjątków z submit()

  1. owinąć Callable or Runnable code in try{} catch{} block

    LUB

  2. Przechowywać future.get() call in try{} catch{} block

    LUB

  3. zaimplementować własną ThreadPoolExecutor i zastąpić afterExecute metoda

Odnośnie tras innych zapytań na

invokeAll:

Wykonuje podane zadania, zwracając listę Futures gospodarstwa ich status i rezultaty, gdy wszystkie zakończyć lub upłynął limit czasu, w zależności od tego, co nastąpi wcześniej.

invokeAny:

Wykonuje podane zadania powrocie wynik ten, który zakończył się pomyślnie (czyli nie powoduje wyjątku), jeśli do zanim dana upływie czasu oczekiwania.

Użyj invokeAll, jeśli chcesz poczekać na zakończenie wszystkich złożonych zadań.

Użyj invokeAny, jeśli szukasz pomyślnego ukończenia jednego zadania spośród N zgłoszonych zadań. W takim przypadku zadania będące w toku zostaną anulowane, jeśli jedno z zadań zakończy się pomyślnie.

Powiązane post z przykładu kodu:

Choose between ExecutorService's submit and ExecutorService's execute

Powiązane problemy