2009-11-24 21 views
5

Estoy implementando una solución rápida parellel como práctica de programación, y cuando terminé, leí la página del tutorial de Java sobre ejecutores, que parece que podría hacer que mi código sea aún más rápido. Desafortunadamente, estaba confiando en join() para asegurarme de que el programa no continúe hasta que todo esté ordenado. En este momento estoy usando:¿Espera a que terminen todos los hilos en un ejecutor?

public static void quicksort(double[] a, int left, int right) { 
    if (right <= left) return; 
    int i = partition(a, left, right); 

    // threads is an AtomicInteger I'm using to make sure I don't 
    // spawn a billion threads. 
    if(threads.get() < 5){ 

     // ThreadSort's run method just calls quicksort() 
     Future leftThread = e.submit(new ThreadSort(a, left, i-1)); 
     Future rightThread = e.submit(new ThreadSort(a, i+1, right)); 

     threads.getAndAdd(2); 
     try { 
      leftThread.get(); 
      rightThread.get(); 
     } 
     catch (InterruptedException ex) {} 
     catch (ExecutionException ex) {} 
    } 
    else{ 
     quicksort(a, left, i-1); 
     quicksort(a, i+1, right); 
    } 
} 

Esto parece funcionar bien, pero si me quedo e.shutdown() justo después de llamar a mi método de ordenación rápida no recursiva(), que tiene un montón de RejectedExecutionExceptions, por lo Supongo que esto no está funcionando tan bien como yo quería.

Así que de todos modos, estoy básicamente tratando de obtener la misma funcionalidad que leftThread.join() pero con un ejecutor, y mis preguntas es:

¿Es esta la mejor manera de esperar hasta que todos los hilos ¿están hechos?
EDIT: Bueno, entonces descubrí por qué tuve un montón de errores después de apagar mi Executor, fue porque estaba llamando a esta función en un bucle (para igualar los tiempos de ejecución) y no crear un nuevo ejecutor .

Respuesta

9

¿Qué tipo de ejecutor estás usando?

ThreadPoolExecutor.awaitTermination() hará lo que está preguntando (en realidad es una operación de unión masiva).

Como un total aparte, ThreadPoolExecutor le permitirá establecer límites en el número de hilos, etc ... (podría ser mejor que ir recursivo como lo que está haciendo si el conteo de subprocesos es alto, no estoy seguro).

PD - Dudo que los ejecutores hagan que su código se ejecute más rápido, pero pueden hacer que su código sea más fácil de leer y mantener. El uso de un grupo de subprocesos hará las cosas más rápidas para este tipo de algoritmo, y el ejecutor facilita el trabajo con grupos de subprocesos.

+1

ThreadPoolExecutors son perfectos para descargar imágenes, si no desea que 1000 hilos congestionen su interfaz de red. Por cierto, estoy bastante seguro de que Android usa ejecutores para administrar sus ASyncTasks detrás de escena. – manmal

1

- Dudo que los ejecutores hará que su código de correr más rápido, pero que puede hacer que su código sea más fácil de leer y mantener. El uso de un subproceso grupo hará que las cosas sean más rápidas para este tipo de algoritmo, y el ejecutor facilita el trabajo con grupos de subprocesos.

Esto no es correcto.

El ejecutor puede ser 'respaldados' por cualquier número de diferentes sistemas de ejecución incluyendo hilos agrupados.

Debe llamar a la clase de fábrica correctamente.

Por otra parte también tiene que decidir sobre una política para hacer frente a situaciones en las que los trabajos se envían a la cola más rápido de lo que pueden ser consumidos, porque es posible que no inicialmente quedarse sin memoria debido a los límites en la ejecución del hilo, pero si pone en cola millones de trabajos, entonces tienen que almacenarse en algún lugar mientras esperan su ejecución.

Cuestiones relacionadas