2012-04-08 14 views
2

Java mulithreadingの質問があります。私は、次のワーカークラスを持っている:私はExecutorServiceを使用していたスレッドで動作するように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 
    { 
} 

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

ThreadWrokerクラスのインスタンスを追加するにはここに起こる:

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

問題があります再帰ツリーの深さがかなり大きいので幅が広いのでThreadWorkersExecutorServiceに追加されているので、bi G入力は、私はので、私は実行するExecutorSirviceに追加しているので、それがメモリ不足ThreadWorkersのginormous数を考えると、引き起こされ

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

を取得します。 ThreadWorkerは、必要なすべてに約40MbのRAMを必要とします。

ExecutorServiceにいくつのスレッド(実行可能なインターフェイスを実装しているクラスのインスタンス)を追加する方法がありますか?だから私は、

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

ように、私は私の再帰との深いや広範に移動し、それらを防ぐことはできません(「//私の問題を防ぐために、いくつかのコードは、」INT)コードの上に表示して、それを追加することができます例外をスローする状況。

よろしくお願いします。Sergey Aganezov jr。

答えて

6

BlockingQueueに裏打ちされたThreadPoolExecutorの作成については、ThreadPoolExecutor.CallerRunsPolicyを使用してください。

この方法では、タスクを実行するために使用できるワーカースレッドがない場合、メインスレッド(新しいジョブを追加しています)はタスク自体を実行し、これ以上ジョブが追加されないようにします。

ThreadPoolExecutorのコンストラクタオプションについては、そのJavadocページで詳しく説明しています。

+0

'TreadPoolExecutor ES =て、新しいThreadPoolExecutor(4、4、10000、TimUnit.MILLISECONDS、新しいArrayBlockingQueue (10))を作成し、' し、それに 'es.setRejectedExecutionHandler(て、新しいThreadPoolExecutorをrejectedHandlerを設定します.CallerRunsPolicy()); '。 これを正しく理解すれば、実行中のスレッドの数が4に達し、キューに入れられたスレッドの数が10に達すると、次の追加されたタスクは拒否され、メインスレッドで実行され、その中の活動。 –

+0

はい、そうです。 – ulmangt

1

あなたのケースは、Java JDKの「fork-join」フレームワークに適していると思います。 (キーワードはGoogle)

Fork-Joinは、「分割」をできるだけ遅らせることで、キュー内のジョブ数を減らすのに役立ちます。

コードをその哲学に再構成する必要があります。

関連する問題