2009-11-24 89 views
5

我正在實現parellel quicksort作爲編程實踐,並且在完成後,我閱讀了Executors上的Java教程頁面,這聽起來像可以讓我的代碼更快。不幸的是,我依靠join()來確保程序不會繼續,直到所有內容都被排序爲止。現在,我使用:等待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); 
    } 
} 

這似乎是工作正常,但如果我跑e.shutdown()我叫之後我的非遞歸快速()方法,它有一堆RejectedExecutionExceptions的,所以我認爲這不像我想要的那樣好。

所以無論如何,我基本上試圖讓相同的功能leftThread.join(),但與執行者,而我的問題是:

這是要等到所有線程的最佳途徑完成?

編輯:好的,所以我想出了爲什麼我關閉了我的執行程序後出現了一堆錯誤,這是因爲我在循環中調用了這個函數(以平衡運行時間)而不是創建新的執行程序。

回答

9

你正在使用什麼類型的執行器?

ThreadPoolExecutor.awaitTermination()會做你在問什麼(這實際上是一個批量連接操作)。作爲一個總的來說,ThreadPoolExecutor將允許你設置對線程數量的限制,等等......(如果線程數量變高,不確定的話,可能比你要做的遞歸更好)。

PS - 我懷疑執行程序會讓你的代碼更快運行,但它們可能會讓你的代碼更易於閱讀和維護。使用線程池可以使這類算法變得更快,而Executor可以很容易地處理線程池。

+1

如果您不希望1000個線程擁塞您的網絡接口,ThreadPoolExecutors非常適合下載圖像。順便說一句,我很確定Android使用Executors在後臺管理他們的ASyncTasks。 – manmal 2012-01-23 10:18:57

1

PS - 我懷疑遺囑執行人將會使你的代碼運行得更快,但 他們可能使你的代碼更容易閱讀和維護。使用線程 池可以使這種算法變得更快,Executor使得使用線程池更容易。

這是不正確的。

執行程序可以由任何數量的不同執行系統「支持」,包括池化線程。

您需要正確調用工廠類。

此外,你還需要一個政策決定,涉及以作業提交到隊列的速度比他們可以食用的情況下,因爲你可能最初耗盡內存由於對線程執行的限制,但是如果你排列了數百萬個工作,那麼他們在等待執行時必須存放在某個地方。