2010-11-13 19 views
7

Estoy escribiendo un programa multiproceso en Java. He escrito algo como estoRejectedExecutionException en Java Threads

exec.execute(p) // where p is a runnable task working on an array 
print array 
exec.shutdown 

El problema que estoy enfrentando es que la matriz se imprime dar el resultado correcto, pero entonces la excepción de ejecución rechazado viene No entiendo por qué cuando los hilos se han procesado y dada la salida correcta ¿por qué viene el error ...

+1

RejectedExecutionException "cuando una tarea no puede ser aceptado para su ejecución ". Es posible que tenga un error simple en el flujo de control, por lo que le sugiero que nos muestre algún código. –

+0

Además, ¿qué implementación específica de 'Executor' estás usando? –

Respuesta

13

Creo que está cerrando a su ejecutor demasiado pronto. Este es un ejemplo de cómo creo que deberías estar trabajando.

public class Main { 
    public static void main(String[] args) throws Exception { 

     // the array to modify 
     final int[] array = new int[1000]; 

     // start the executor (that modifies the array) 
     ExecutorService executor = Executors.newFixedThreadPool(10); 

     for (int i = 0; i < 1000; i++) { 
      final int c = i; 
      executor.execute(new Runnable() { 
       @Override 
       public void run() { 
        array[c] = c; 
       } 
      }); 
     } 

     // wait for all tasks to quit 
     executor.shutdown(); 
     while (!executor.awaitTermination(10, TimeUnit.SECONDS)); 

     // print the array 
     System.out.println(Arrays.toString(array)); 
    } 
} 

También tenga en cuenta que el trabajo en la misma matriz al mismo tiempo podría causar inconsistencia - usted debe estar realmente seguro de que usted no está haciendo el trabajo en la matriz que depende de la matriz.

+3

ExecutorService.shutdown() no espera a que se cierren las tareas, simplemente le dice al ExecutorService que no acepte más tareas y finalice. El ExecutorService.awaitTermination() debe llamarse después de la llamada a shutdown() para bloquear el hilo de llamada hasta que las tareas hayan finalizado. – Rich

+0

¡Buen punto! Actualizado – dacwe

+0

Creo que el ciclo while no es necesario ya que el 'executor.awaitTermination' se bloquea a sí mismo (?) – IHeartAndroid

0

Una opción podría ser más conseguir el futuro al momento de enviar a albacea y luego bloquear el futuro llamando al llegar

6

problema es que todavía está presentando nuevas tareas incluso después de llamar shutdown(). Entonces, usar executor.awaitTermination() no ayudará.

Para solucionar el problema, verifique si el ejecutor no está apagado al momento de enviar la tarea.

ejemplo:

if (!executor.isShutdown()) 
{ 
    executor.execute(new Runnable() { 
         @Override 
         public void run() { 
           array[c] = c; 
         } 
        }); 
} 

creo que sirve ...

+0

En mi caso, el ejecutor se cerró exactamente entre las líneas if y execute. Entonces, si hay simultaneidad involucrada, debe colocar las llamadas execute() y shutdown() en bloques/métodos sincronizados. –

2

he usado para apagar los ejecutores creados en el gancho de cierre en tiempo de ejecución se lanza

Runtime.getRuntime().addShutdownHook(new Thread() { 

      public void run() { 
      if(!eExecutor.isShutdown()) { 
       eExecutor.shutdown(); 
       // await termination code 
       } 
      } 

     });