2012-03-20 4 views
6

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?

+0

Qual è il tuo thread principale farlo che non può essere bloccato? – EJP

+0

Quale toolkit UI stai usando? – Dev

risposta

2

isTerminated() farà

nota, tuttavia, che sia awaitTermination e isTerminated solo vi darà un risultato significativo dopo aver chiamato shutdown

+0

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

7

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.

+1

Non ha mai menzionato che si tratta di un'applicazione Swing e, in caso contrario, uno SwingWorker non sarebbe appropriato. –

+1

Ho dimenticato di menzionare che si tratta di un'applicazione Swing! – Trota

+0

Dopo aver letto di più su SwingWorker mi sono reso conto che questa è una soluzione abbastanza semplice al mio problema! Grazie Dev! – Trota

4

Perché non utilizzare CountDownLatch e quindi notificare il thread principale quando il latch è stato completato.

+1

Buona idea; c'è un bell'esempio citato [qui] (http://stackoverflow.com/a/3588523/230513). – trashgod

+1

@trashgod ha appena commentato nel tuo post: l'esempio ha un piccolo problema nell'accesso al textComponent dell'EDT – kleopatra

2

È 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(); 
2

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

+0

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