2012-02-23 15 views
5

Qual è il modo migliore per gestire RejectedExecutionException durante l'utilizzo di ThreadPoolExecutor in Java?Come gestire RejectedExecutionException con ThreadPoolExecutor in java

Voglio assicurarmi che l'attività inviata non sia trascurata e debba essere sicuramente eseguita. A partire da ora non ci sono requisiti in tempo reale per svolgere l'attività.

Una delle cose che pensavo potesse essere fatta era attendere in un ciclo finché non so che c'è spazio nella coda eseguibile, e poi andare avanti e aggiungerlo alla coda.

Sarebbe felice se le persone possano condividere le loro esperienze.

Aggiunta la soluzione possibile ho pensato di:

while(executor.getQueue().remainingCapacity <= 0){ 
// keep looping 
Thread.sleep(100); 
}; 
//if the loop exits ,indicates that we have space in the queue hence 
//go ahead and add to the queue 
executor.execute(new ThreadInstance(params)); 
+0

Questo creerà una condizione di competizione se più di un thread sta tentando di farlo. Brucia inoltre una CPU che potrebbe richiedere più tempo per l'executor di cancellare la coda. per esempio. se c'è una sola CPU per il sommatore e l'esecutore, questo potrebbe essere disastroso. –

+0

Dall'architettura ci sarebbe solo un thread che lo fa, e per gestire il consumo di tempo della CPU, sto facendo il thread sleep.Come fa ora? – Neeraj

+0

Dormire, anche per un breve periodo (anche 1 - 10 ms) è molto meglio di no. 100 ms è anche un buon valore. Questo va bene se hai solo un thread di pubblicazione. –

risposta

3

Vorrei modificare il comportamento della coda. per esempio.

public class MyBlockingQueue<E> extends ArrayBlockingQueue<E> { 
    private final long timeoutMS; 

    public MyBlockingQueue(int capacity, long timeoutMS) { 
     super(capacity); 
     this.timeoutMS = timeoutMS; 
    } 

    @Override 
    public boolean offer(E e) { 
     try { 
      return super.offer(e, timeoutMS, TimeUnit.MILLISECONDS); 
     } catch (InterruptedException e1) { 
      Thread.currentThread().interrupt(); 
      return false; 
     } 
    } 
} 

Questo attenderà che la coda si esaurisca prima di arrendersi.

+0

Non riesco a fare qualcosa come while (executor.getQueue(). RemainingCapacity <= 0) {// keep looping}; // se il ciclo termina, indica che abbiamo spazio nella coda quindi // vai avanti e aggiungi alla coda executor.execute (new ThreadInstance (params)); Questa sembra essere una soluzione senza dover creare la mia istanza di ArrayBlockingQueue. – Neeraj

+0

mal aggiungere il codice nella mia domanda.Essi sembra spento. – Neeraj

+1

Se hai una condizione di gara. Non è garantito che un altro thread non possa riempire la coda nel tentativo di fare la stessa cosa. Non devi creare il tuo ArrayBlockingQueue, puoi copiare il mio. ;) –

2

Se si è costretti vostro pool di thread per consentire solo un certo numero di thread simultanei (generalmente una buona cosa), allora l'applicazione deve in qualche modo push di nuovo sul codice chiamante, quindi quando si riceve una RejectedExecutionException da ThreadPoolExecutor è necessario indicare questo al chiamante e il chiamante dovrà gestire il nuovo tentativo.

Una situazione analoga è un server Web sotto carico pesante. Un client si connette, il server Web deve restituire un 503 - Servizio non disponibile (generalmente una condizione temporanea) e il client decide cosa fare al riguardo.

Problemi correlati