2012-02-23 15 views
5

¿Cuál es la mejor forma de manejar RejectedExecutionException mientras usa ThreadPoolExecutor en Java?Cómo manejar RejectedExecutionException con ThreadPoolExecutor en java

que quieren asegurarse de que la tarea presentada no debe ser pasado por alto y debe sin duda se ejecutan. A partir de ahora no hay requisitos duros en tiempo real para realizar la tarea.

Una de las cosas que pensé que se podía hacer era esperar en un bucle hasta que sepa que no hay espacio en la cola ejecutable, y luego seguir y añadirlo a la cola.

sería feliz si la gente puede compartir sus experiencias.

Adición de la posible solución que a pesar de:

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

Esto creará una condición de carrera si hay más de un hilo tratando de hacer esto. También quemará una CPU que podría significar que el ejecutor tardará más en borrar la cola. p.ej. si solo hay una CPU para el sumador y el ejecutor, esto podría ser desastroso. –

+0

Desde la arquitectura solo habría un hilo haciendo esto, y para manejar el tiempo de CPU consumido, haré que el hilo duerma. ¿Cómo se ve esto ahora? – Neeraj

+0

Dormir, incluso por un corto tiempo (incluso 1 - 10 ms) es mucho mejor que no hacerlo. 100 ms es un buen valor también. Esto está bien si solo tiene un hilo de publicación. –

Respuesta

3

Cambiaría el comportamiento de su cola. p.ej.

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; 
     } 
    } 
} 

Esto esperará a que la cola se drene antes de darse por vencido.

+0

No puedo simplemente hacer algo como while (executor.getQueue(). RemainingCapacity <= 0) {// keep looping}; // si el bucle termina, indica que tenemos espacio en la cola, por lo tanto // seguir adelante y agregar a la cola de executor.execute (nueva ThreadInstance (params)); Esto parece ser una solución sin tener que crear mi propia instancia de ArrayBlockingQueue. – Neeraj

+0

Agregaré el código en mi pregunta. Aquí parece que no. – Neeraj

+1

Tienes una condición de carrera si lo haces. No hay garantía de que otro hilo pueda no llenar la cola intentando hacer lo mismo. No tiene que crear su propia ArrayBlockingQueue, puede copiar la mía. ;) –

2

Si ha limitado su grupo de subprocesos para permitir sólo un cierto número de hilos concurrentes (generalmente una buena cosa), entonces la aplicación necesita de algún modo push de vuelta en el código de llamada, por lo que cuando se recibe un RejectedExecutionException del ThreadPoolExecutor que necesita para indicar esto a la persona que llama y la persona que llama tendrá que manejar el reintento.

Una situación análoga es un servidor web bajo una carga pesada. Un cliente se conecta, el servidor web debe devolver un 503 - Servicio no disponible (generalmente una condición temporal) y el cliente decide qué hacer al respecto.

Cuestiones relacionadas