Pregunta

Estoy implementando una ordenación rápida paralela como práctica de programación y, una vez que terminé, leí la página del tutorial de Java en Executors, que parece que podrían hacer que mi código sea aún más rápido.Desafortunadamente, confiaba en join() para asegurarme de que el programa no continúe hasta que todo esté ordenado.Ahora mismo estoy usando:

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 ejecuto e.shutdown() justo después de llamar a mi método Quicksort() no recursivo, tiene un montón de RejectedExecutionExceptions, así que supongo que esto no está funcionando tan bien como quería.

De todos modos, básicamente estoy tratando de obtener la misma funcionalidad que leftThread.join() pero con un Ejecutor, y mi pregunta es:

¿Es esta la mejor manera de esperar hasta que todos los hilos estén terminados?

EDITAR:Bien, descubrí por qué recibí un montón de errores después de apagar mi Ejecutor, fue porque estaba llamando a esta función en un bucle (para igualar los tiempos de ejecución) y no estaba creando un nuevo Ejecutor.

¿Fue útil?

Solución

¿Qué tipo de ejecutor está usando?

ThreadPoolExecutor .awaitTermination() hará lo que usted está planteando (que es efectivamente una mayor operación de combinación).

Como un total de lado, ThreadPoolExecutor le permite a los límites establecidos en el # de hilos, etc ... (podría ser mejor que ir recursiva como lo que está haciendo si el número de hilos pasa a nivel alto, no estoy seguro).

PS - dudo que los ejecutores hará que su código de correr más rápido, pero pueden hacer que su código sea más fácil de leer y mantener. El uso de un conjunto de subprocesos hará las cosas más rápido para este tipo de algoritmo, y el Ejecutor hace que sea fácil trabajar con grupos de subprocesos.

Otros consejos

Tome un vistazo a Executors.newFixedThreadPool que le permite crear un conjunto de hilos a lo sumo n (se deshace de su "si") y el ExecutorService.shutdown método y el ExecutorsService.awaitTermination método.

Se puede usar un CountDownLatch

  

PS - dudo que los ejecutores hará que su código de correr más rápido, pero   que pueden hacer que su código sea más fácil de leer y mantener. El uso de un hilo   piscina hará las cosas más rápido para este tipo de algoritmo, y el   Ejecutor hace que sea fácil trabajar con grupos de subprocesos.

Esto no es correcto.

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

Es necesario llamar a la clase de fábrica correctamente.

Por otra parte también es necesario para 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 quedado sin memoria debido a los límites de la ejecución del hilo, pero si te cola millones de puestos de trabajo, entonces ellos tienen que ser almacenados en algún lugar mientras esperan para su ejecución.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top