Ho riscontrato un problema due volte in cui un thread del produttore produce N elementi di lavoro, li invia a un ExecutorService
e quindi deve attendere fino a quando tutti gli elementi N sono stati elaborati.CountDownLatch flessibile?
Caveats
- N non è noto in anticipo. Se lo fosse vorrei semplicemente creare un
CountDownLatch
e quindi avere il thread di produzioneawait()
fino al completamento di tutti i lavori. - utilizzando un
CompletionService
non è appropriato perché anche se il mio thread produttore ha bisogno di bloccare (cioè chiamandotake()
) non c'è alcun modo di segnalando che tutto il lavoro è completo, per causare il filo produttore a smettere di aspettare.
mia soluzione preferita attuale è quella di utilizzare un contatore intero, e incremento questo ogni volta che viene presentata una voce di lavoro e decremento quando un elemento di lavoro viene elaborato. Dopo la sottomissione di tutti gli N task, il thread del mio produttore dovrà attendere un lock, controllando se counter == 0
ogni volta che viene notificato. Il/i thread/i del consumatore dovrà notificare al produttore se ha diminuito il contatore e il nuovo valore è 0.
C'è un approccio migliore a questo problema o c'è un costrutto adatto in java.util.concurrent
Dovrei usare piuttosto di "rotolare il mio"?
Grazie in anticipo.
In che momento il produttore sa quanti oggetti di lavoro ci sono? Quando l'ultimo oggetto è stato prodotto? –
La tua soluzione attuale potrebbe soffrire di una condizione di competizione: produrre elemento 1 -> contatore ++ -> processo articolo 1 -> contatore-- -> produrre elemento 2. Poiché il contatore è stato decrementato prima che il produttore abbia prodotto l'articolo successivo, il produttore pensa di essere pronto. –
@rwwilden: Hai ragione nel senso che questo scenario potrebbe verificarsi. Tuttavia, il mio produttore ispezionerà/aspetterà sul bancone solo dopo aver inviato * tutti * gli articoli di lavoro e quindi non rappresenta una condizione di competizione in questo caso particolare. – Adamski