Domanda

Sto usando il framework Executor per dare il via a diversi thread usando un pool di thread, ovvero newFixedThreadPool. Uso threadpool.submit (aThread) per inviare i lavori che devono essere eseguiti dal threadpool e questo funziona bene, tuttavia devo determinare quando tutti i thread sono completi in modo da poter continuare con altre elaborazioni. Ho esaminato l'utilizzo di Future.get () che blocca fino a quando il thread non è completo, il problema qui è che si blocca fino a quando non è disponibile un risultato. Ho anche cercato di usare continuamente il metodo isTerminated () seguito da uno sleep dopo aver eseguito l'arresto per verificare se tutti i thread sono completi ma questo non mi sembra pulito. C'è un altro modo più pulito per farlo? Inoltre, se viene sollevata un'eccezione in uno dei thread, voglio essere in grado di terminare tutti gli altri thread in esecuzione e anche di interrompere l'avvio di qualsiasi thread in coda nel pool. Qual è il miglior meccanismo per farlo?

Non vedo l'ora di ascoltare le tue risposte

TIA

È stato utile?

Soluzione

Uno dei modi più chiari per affrontare questo è modificando le attività che vengono inviate. Registrando un callback con ogni attività, può notificare il completamento normale o un'eccezione senza alcun polling da parte del thread principale.

Puoi scrivere un semplice wrapper che lo farà per qualsiasi eseguibile .

Oppure, seguendo quell'esempio, puoi estendere l'idea per avvolgere qualsiasi Callable .

class CallbackTask<T>
  implements Callable<T>
{

  private final Callable<? extends T> task;

  private final Callback<T> callback;

  CallbackTask(Callable<? extends T> task, Callback<T> callback)
  {
    this.task = task;
    this.callback = callback;
  }

  public T call()
    throws Exception
  {
    try {
      T result = task.call();
      callback.complete(result);
      return result;
    }
    catch (Exception ex) {
      callback.failed(ex);
      throw ex;
    }
  }

}

Altri suggerimenti

Usa ExecutorService #shutdown () e quindi ExecutorService # awaitTermination ()

Ad esempio:

ExecutorService service = Executors.newCachedThreadPool();
service.submit(...);
service.submit(...);
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);

// All tasks have now finished

Per quanto riguarda la notifica di quando un'attività ha esito negativo con un'eccezione. Dovrai fornire un ThreadFactory al Servizio Executor che imposta un gestore di eccezioni "non rilevato" " per ogni thread che crea. Questo gestore di eccezioni può quindi terminare le attività in esecuzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top