Ho un'implementazione multithreading in cui creo un ExecutorService e invio attività da eseguire, voglio sapere quando tutti i thread sono stati inviati hanno finito senza bloccare il thread principale e l'interfaccia utente. Ho provato ExecutorService.awaitTermination()
ma blocca il thread principale e l'interfaccia utente. Ho cercato molto ma non riesco a trovare un modo elegante per farlo. Attualmente sto pensando di creare un altro thread che conta la quantità di thread finiti e lancia un evento quando tutti hanno finito, ma questo non è un buon approccio e volevo una soluzione migliore!ExecutorService, come sapere quando tutti i thread sono finiti senza bloccare il thread principale?
ExecutorService, come sapere quando tutti i thread sono finiti senza bloccare il thread principale?
risposta
isTerminated()
farà
nota, tuttavia, che sia awaitTermination
e isTerminated
solo vi darà un risultato significativo dopo aver chiamato shutdown
Ho trovato alcune cose su isTerminated() ma ancora, penso di aver bisogno di eseguirlo su un "thread laterale" per verificare costantemente se restituisce true che mi porta alla mia soluzione iniziale! – Trota
Utilizzare un arresto per la piscina SwingWorker
filo e chiamare awaitTermination()
. Ciò impedirà all'interfaccia utente di bloccare e chiamare done()
dal thread di invio eventi sull'implementazione SwingWorker che è possibile utilizzare per attivare le modifiche dell'interfaccia utente necessarie.
Se si desidera tenere traccia dei thread che eseguono tramite un aggiornamento dell'interfaccia utente, è possibile utilizzare il thread di lavoro per monitorare questo in un ciclo e chiamare publish()
con argomenti che vengono passati all'implementazione di process()
sull'EDT.
Non ha mai menzionato che si tratta di un'applicazione Swing e, in caso contrario, uno SwingWorker non sarebbe appropriato. –
Ho dimenticato di menzionare che si tratta di un'applicazione Swing! – Trota
Dopo aver letto di più su SwingWorker mi sono reso conto che questa è una soluzione abbastanza semplice al mio problema! Grazie Dev! – Trota
Perché non utilizzare CountDownLatch e quindi notificare il thread principale quando il latch è stato completato.
È possibile mantenere un thread separato per monitorare quando l'istanza del servizio esecutore si spegne:
final ExecutorService execSvc = ...;
execSvc.submit(task1);
...
execSvc.submit(taskN);
// important to request the exec service to shut down :)
execSvc.shutdown();
new Thread(new Runnable() {
public void run() {
while (!execSvc.isTerminated()) {
try {
execSvc.awaitTermination(60, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// ignore exception
}
}
System.out.println("ExecSvc.run: exec service has terminated!");
// possibly submit a task using SwingUtilities.invokeLater() to update the UI
}
}).start();
Utilizzando CountDownLatch
CountDownLatch latch = new CountDownLatch(totalNumberOfTasks); ExecutorService taskExecutor = Executors.newFixedThreadPool(4); while(...) { taskExecutor.execute(new MyTask()); } try { latch.await(); } catch (InterruptedException E) { // handle }
e nel rispetto del compito (allegare in try/finally)
latch.countDown();
Oppure su ExecutorService si chiama shutdown() e quindi awa itTermination()
ExecutorService taskExecutor = Executors.newFixedThreadPool(4); while(...) { taskExecutor.execute(new MyTask()); } taskExecutor.shutdown(); try { taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); } catch (InterruptedException e) { ... }
Anche dare un'occhiata al THIS risposta
A meno che non mi sbaglio, nessuna di queste soluzioni sta affrontando la domanda fondamentale dell'OP che è quella di evitare il blocco sul main filo. – Trevor
Qual è il tuo thread principale farlo che non può essere bloccato? – EJP
Quale toolkit UI stai usando? – Dev