2009-11-24 20 views
5

Sto implementando un quicksort parellel come pratica di programmazione, e dopo che ho finito, ho letto la pagina di tutorial di Java su Executor, che suona come se potesse rendere il mio codice ancora più veloce. Sfortunatamente, mi stavo affidando a join() per assicurarmi che il programma non continuasse fino a quando tutto è stato ordinato. In questo momento sto usando:Attendi che finiscano tutti i thread in un Executor?

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

Questo sembra funzionare bene, ma se corro e.shutdown() subito dopo che io chiamo il mio metodo Quicksort non ricorsivo(), ha un mucchio di RejectedExecutionExceptions, così Presumo che questo non funzioni come volevo.

Quindi, comunque, praticamente sto cercando di ottenere la stessa funzionalità leftThread.join(), ma con un esecutore, e la mia domanda è:

È questo il modo migliore per aspettare fino a quando tutti i thread sono fatti?


EDIT: Ok, ho capito perché ho avuto un sacco di errori dopo aver spento il mio Executor, era perché stavo chiamando questa funzione in un ciclo (per uniformare i tempi di esecuzione) e non creare un nuovo Executor .

risposta

9

Che tipo di esecutore stai utilizzando?

ThreadPoolExecutor.awaitTermination() farà quello che stai chiedendo (è effettivamente un'operazione di massa).

Come totale, ThreadPoolExecutor consentirà di impostare limiti sul numero di thread, ecc ... (potrebbe essere meglio che andare in modo ricorsivo come quello che si sta facendo se il conteggio dei thread aumenta, non è sicuro).

PS - Dubito che gli esecutori faranno funzionare il tuo codice più velocemente, ma potrebbero rendere il tuo codice più facile da leggere e gestire. L'utilizzo di un pool di thread renderà le cose più veloci per questo tipo di algoritmo e l'Executor facilita il lavoro con i pool di thread.

+1

ThreadPoolExecutors sono perfetti per il download di immagini, se non si desidera che 1000 thread congestionino l'interfaccia di rete. BTW Sono abbastanza sicuro che Android utilizzi gli Executor per gestire i loro ASyncTask dietro le quinte. – manmal

1

PS - dubito che esecutori renderà il vostro codice di correre più velocemente, ma essi possono rendere il codice più facile da leggere e gestire. L'utilizzo di un thread pool renderà le cose più veloci per questo tipo di algoritmo e l'Executor facilita il lavoro con i pool di thread.

Questo non è corretto.

L'executor può essere "supportato" da qualsiasi numero di diversi sistemi di esecuzione, inclusi i thread in pool.

È necessario chiamare correttamente la classe di fabbrica.

Inoltre, è necessario decidere un criterio per gestire le situazioni in cui i lavori vengono inoltrati alla coda più rapidamente di quanto possano essere consumati, poiché è possibile che non sia esaurito la memoria a causa dei limiti nell'esecuzione del thread, ma se metti in coda milioni di lavori, allora devono essere immagazzinati in un posto mentre aspettano l'esecuzione.

Problemi correlati