2013-05-14 13 views
7

Sto scrivendo un'applicazione in Java che utilizza ExecutorService per l'esecuzione di più thread.Monitoraggio delle attività completate in ExecutorService

Desidero inviare più attività (migliaia alla volta) all'Esecutore come Callables e al termine, recuperare il risultato. Il modo in cui mi sto avvicinando è ogni volta che chiamo funzione submit(), ottengo un Futuro che memorizzo in un ArrayList. Successivamente passo l'Elenco a un thread che continua a scorrere su di esso, chiamando la funzione future.get() con un timeout per vedere se l'attività è stata completata. è questo il giusto approccio o troppo troppo inefficiente?

EDIT --- Ulteriori informazioni --- Un altro problema è che ogni Callable impiega una quantità diversa di tempo di elaborazione. Quindi, se prendo semplicemente il primo elemento dall'elenco e chiamo get() su di esso, esso verrà bloccato mentre i risultati di altri potrebbero diventare disponibili e il programma non lo saprà. Questo è il motivo per cui devo continuare a ripetere i timeout.

grazie in anticipo

+0

vi consiglio di prendere in considerazione le utilità ListenableFuture nella biblioteca Guava: https://code.google.com/p/guava-libraries/wiki/ListenableFutureExplained – Enwired

risposta

1

Si noti che la chiamata a Future.get bloccherà fino a quando la risposta sarà disponibile. Quindi non hai bisogno di un altro thread per scorrere l'elenco di array.

Vedi qui https://blogs.oracle.com/CoreJavaTechTips/entry/get_netbeans_6

+0

capito. Ma invio migliaia di compiti a ExecutorService in sequenza. Quindi ho bisogno di memorizzare i Futures da qualche parte per riferimento futuro. Mentre sono bloccato sul primo Callable, un altro potrebbe essere stato completato e non lo saprò. Qualche idea? –

+0

La loro memorizzazione nell'elenco è soddisfacente. Arriverete a quello che è terminato non appena quello che è bloccato è completo. – Woody

+0

La loro memorizzazione nell'elenco è soddisfacente. Arriverete a quello che è terminato non appena quello che è bloccato è completo. Se è necessario essere avvisati di ogni singolo completamento come e quando è successo, ad es. per aggiornare un'interfaccia utente, in generale, è necessario utilizzare un meccanismo di notifica anziché il polling. Penso che Future.get sia un meccanismo troppo generico per questo scopo. – Woody

6

è questo l'approccio giusto o è di troppo inefficiente?

Questo non è l'approccio corretto di per sé. Stai eseguendo inutilmente il controllo ArrayList per il completamento dell'attività.

Questo è molto semplice: basta usare: CompletionService. Puoi facilmente avvolgere il tuo esecutore esistente in esso. Da JavaDocs:

I produttori presentano compiti per l'esecuzione. I consumatori accettano le attività completate e elaborano i risultati nell'ordine in cui sono stati completati.

In sostanza, CompletionService fornisce un modo per ottenere il risultato di nuovo semplicemente chiamando take(). È una funzione di blocco e il chiamante bloccherà fino a quando i risultati saranno disponibili.


Problemi correlati