2012-04-08 49 views
2

我哈瓦一個Java mulithreading問題。我有以下的工人類:Java的ExecutorService的堆空間問題

public class ThreadWorker implements Runnable { 

    //some code in here 

    public void run(){ 
     // invokes some recursion method in the ThreadWorker itself, 
     // which will stop eventually 
    { 
} 

要與我使用的是ExecutorService線程工作:ThreadWroker類的

public static int THREAD_NUMBER = 4; 
public static ExecutorServide es = Executors.newFixedThreadPool(THREAD_NUMBER); 

添加實例發生在這裏:

public void recursiveMethod(Arraylist<Integers> elements, MyClass data){ 
    if (elements.size() == 0 && data.qualifies()){ 
     ThreadWorker tw = new ThreadWorker(data); 
     es.execute(tw); 
     return; 
    } 



    for (int i=0; i< elements.size(); i++){ 
      // some code to prevent my problem 
      MyClass data1 = new MyClass(data); 
      MyClass data2 = new MyClass(data); 
      ArrayList<Integer> newElements = (ArrayList<Integer>)elements.clone(); 
      data1.update(elements.get(i)); 
      data2.update(-1 * elements.get(i)); 
      newElements.remove(i); 
      recursiveMethod(newElements, data1); 
      recursiveMethod(newElements, data2);  
    {  
} 

的問題是該遞歸樹的深度是相當大的,所以它的寬度,所以很多ThreadWorkers是在雙向一段時間後加入到ExecutorService,所以加速度輸入一個獲得

Exception in thread "pool-1-thread-2" java.lang.OutOfMemoryError: Java heap space 

時所引起,因爲我認爲,因爲的ThreadWorkers一個極大的相數我加入到ExecutorSirvice執行,所以它運行的內存。每ThreadWorker需要大約40 MB的RAM用於所有需要。

是否有一種方法可以讓ExecutorService有多少線程(實現可運行接口的類的實例)?因此,我可以在上面的代碼所示(INT的「//一些代碼,以防止我的問題」),作爲

while ("number of threads in the ExecutorService" > 10){ 
    Thread.sleep(10000); 
} 

,所以我不會去深或寬,我的遞歸和防止那些添加它異常投擲情況。

真誠,謝爾蓋Aganezov JR。

回答

6

如何使用ThreadPoolExecutor.CallerRunsPolicy創建支持BlockingQueueThreadPoolExecutor

這樣,當沒有可用於運行任務的工作線程時,主線程(即添加新作業)將自行運行任務,從而防止添加更多作業。

關於ThreadPoolExecutor在其Javadoc頁面的構造函數選項有更多詳細信息。

+0

創建 'TreadPoolExecutor ES =新的ThreadPoolExecutor(4,4,10000,TimUnit.MILLISECONDS,新ArrayBlockingQueue (10));' 然後設置rejectedHandler到它 'es.setRejectedExecutionHandler(新的ThreadPoolExecutor .CallerRunsPolicy());'。 之後,如果我理解它是正確的,它會處理我的問題,因爲一旦運行的線程數達到4,並且排隊的線程數達到10,下一個添加的任務將被拒絕並執行主線程,停止所有其他線程活動。 – 2012-04-08 06:41:43

+0

是的,這是正確的。 – ulmangt 2012-04-08 14:56:56

1

我認爲你的情況與Java JDK的「fork-join」框架非常匹配。 (Google針對該關鍵字)

Fork-Join通過儘可能延遲「拆分」來幫助您減少隊列中的作業數量。

你必須雖然重新制定你的代碼,這樣的理念。