5

私はJavaマルチスレッドの質問があります。私は次の労働者クラスを持っています:

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:を使用しています。

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

問題は、再帰ツリーの深さが非常に大きいため、幅であるため、に多くの値ThreadWorkersが追加されるExecutorServiceため、大きな入力をしばらく行った後、getを取得することです。

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

これは、実行するためにThreadWorkers追加している膨大な数のiが原因だと思うので、メモリが不足していることが原因です。ExecutorSirvice必要なものすべてThreadWorkerに約40MbのRAMが必要です。

追加されたスレッド(実行可能なインターフェイスを実装するクラスのインスタンス)の数を取得する方法はありますExecutorServiceか?したがって、上記のコード( "//問題を防ぐためのコード")に追加できます。

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

ですから、私は自分の再帰を深くしたり広めたりして、これらの例外をスローする状況を防ぐことはしません。

よろしくお願いいたします。SergeyAganezovjr。

4

2 に答える 2

6

ThreadPoolExecutor.CallerRunsPolicyを使用してバックアップされたThreadPoolExecutorを作成するのはどうですか。BlockingQueue

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

ThreadPoolExecutorのコンストラクターオプションの詳細については、Javadocページを参照してください。

于 2012-04-08T05:22:23.833 に答える
1

あなたのケースは、JavaJDKの「フォークジョイン」フレームワークにぴったりだと思います。(そのキーワードのGoogle。)

Fork-Joinは、「分割」を可能な限り遅らせることにより、キュー内のジョブの数を減らすのに役立ちます。

ただし、コードをその哲学に再定式化する必要があります。

于 2012-04-09T15:30:22.047 に答える