2013-09-10 10 views
27

Sto imparando a utilizzare exectorServices per raggruppare threads e inviare attività. Ho un semplice programma sottodifferenza tra executor.submit ed executor.execute in questo codice in Java?

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()); 
     } 
    } 
     } 

Lo fa niente di speciale, ma crea due threads e presenta 5 funzioni in totale. Dopo che ogni thread completa il suo compito, prende il successivo, Nel codice sopra, io uso executor.submit. Ho anche cambiato in executor.execute. Ma non vedo alcuna differenza nell'output. In che modo i metodi submit and execute sono diversi? questo ciò che il API dice

metodo di invio estende il metodo di base Executor.execute (java.lang.Runnable) creando e restituendo un futuro che può essere utilizzato per annullare l'esecuzione e/o attendere per il completamento. I metodi invokeAny e invokeAll eseguono le forme più comuni di esecuzione di massa, eseguendo una raccolta di attività e quindi aspettando che ne venga completato almeno uno o tutti. (Class ExecutorCompletionService può essere utilizzato per scrivere varianti personalizzate di questi metodi.)

Ma non mi è chiaro cosa significhi esattamente? Grazie

+0

domanda utile. Ha valore per postarlo qui. – MKod

risposta

29

Come si vede dal JavaDoc execute(Runnable) non restituisce nulla.

Tuttavia, submit(Callable<T>) restituisce un oggetto Future che permette un modo per annullare programatically il filo conduttore seguito così come ottenere il T che viene restituito quando i Callable è completa. Vedere JavaDoc of Future per maggiori dettagli

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

Inoltre, se future.get() == null e non genera alcuna eccezione quindi Runnable eseguito con successo

30

La differenza è che execute inizia semplicemente il compito senza ulteriori indugi, considerando submit restituisce un oggetto Future per gestire l'attività. È possibile fare le seguenti cose con l'oggetto Future:

  • annullare l'attività prematuramente, con il metodo cancel.
  • Attendere il completamento dell'operazione, con get.

L'interfaccia Future è più utile se si invia un Callable al pool. Il valore restituito del metodo call verrà restituito quando si chiama Future.get. Se non si mantiene un riferimento allo Future, non c'è alcuna differenza.

3

Submit - Restituisce oggetto futuro, che può essere utilizzato per controllare risultato del compito presentato. Può essere utilizzato per annullare o controllare isDone ecc.

Esegui - non restituisce nulla.

5

execute: usarlo per il fuoco e dimenticare le chiamate

submit: Usalo per ispezionare il risultato della chiamata di metodo e di prendere i provvedimenti opportuni sulla Future obiettò restituito dalla chiamata

grande differenza: Exception movimentazione

submit() nasconde senza maniglia Exception nella struttura stessa.

execute() getti non gestiti Exception.

soluzione per la gestione delle eccezioni con submit()

  1. Avvolgete il vostro Callable or Runnable code in try{} catch{} block

    O

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

    O

  3. implementare il proprio metodo di ThreadPoolExecutor e sovrascrivere afterExecute

Per quanto riguarda turistici altre query sulla

invokeAll:

esegue i compiti assegnati, restituendo una lista di Futures tenendo il loro status e risultati quando tutti completare o il timeout scade, a seconda dell'evento che si verifica per primo.

invokeAny:

esegue i compiti assegnati, restituendo il risultato di uno che ha completato con successo (cioè, senza gettare un'eccezione), se del caso fare prima della data timeout trascorre.

Utilizzare invokeAll se si desidera attendere il completamento di tutte le attività inoltrate.

Utilizzare invokeAny se si sta cercando di completare con successo un'attività in N attività inviate. In questo caso, le attività in corso verranno annullate se una delle attività viene completata correttamente.

post correlati con esempio di codice:

Choose between ExecutorService's submit and ExecutorService's execute

Problemi correlati