Come elaboro in modo efficiente più risultati da un servizio di esecutore
-
27-10-2019 - |
Domanda
Non sono nuovo a Executorservice, ma non sono sicuro del mio approccio a questo. Potrei avere a che fare con un massimo di 100 thread per un'attività nota. Sto usando il formato generale di seguito, in cui creo un elenco di futuretask, quindi lo invio al servizio esecutivo. Executorservice restituisce e aggiunge questi risultati in sospeso a un altro elenco. Quindi itero su questo elenco, chiamando Get () su ogni risultato in sospeso.
La mia query è: questo blocco su ciascun Get () a sua volta fino a quando tutti i 100 thread non saranno completati? C'è un modo migliore per farlo?
E ho ragione nel presupponendo che GET () restituisca il risultato del metodo Call () di implementazione Callable? Sto usando la classe FutureTask predefinita e non l'ho sottoclassata.
ExecutorService exec = Executors.newFixedThreadPool( NUM_THREADS );
List<JobClass> originalList = new ArrayList<JobClass>();
List<SomeOtherClass> pendingResult = new ArrayList<SomeOtherClass>();
List<Future<SomeOtherClass>> resultList = new ArrayList<Future<SomeOtherClass>>();
for( JobClass sc : originalList )
pendingResult.add( submit( sc );
for( Future<SomeOtherClass> future : futures )
resultList.add( future.get(5, TimeUnit.SECONDS) );
Soluzione
Buona domanda, se ti capisco correttamente, sei preoccupato per il consumo del risultato di compiti completati. Sì, il thread bloccerà. La risposta di Java è usare il Completationervice.
Come menzionato nella pagina di documentazione "un servizio che disaccoppia la produzione di nuovi compiti asincroni dal consumo dei risultati di compiti completati".
Altri suggerimenti
Se procedi solo se tutte le attività sono completate, puoi fare ciò che hai suggerito. Non importa in quale compiti ordini completi. Tuttavia, se è necessario passare i risultati delle attività ad altro processore il più presto possibile o fare qualcos'altro mentre le attività stanno eseguendo, è possibile che si verifichi se l'attività è completa per prima utilizzando l'utilizzo isDone
metodo, ad esempio, e chiama get()
Se è completo.