2016-04-05 9 views
1

私はForkJoinPoolを使用してタスクを並列に実行します。私のプログラムのログアウトを見ると、ForkJoinPoolは自分のタスクを実行するために膨大な量の作業者を作成しているようです(このようなログエントリがあります:05 Apr 2016 11:39:18,678 [ForkJoinPool-2-worker-2493] <message>)。ForkJoinPoolは膨大な量の作業者を作成します

その後、私はForkJoinPoolで構成されるか、または私が何か間違ったことをやっている並列処理の数に応じて実行されて作成された各タスクのための労働者がありますか?ここで私はそれを行う方法です:

public class MyClass { 
    private static final int NUM_CORES = Runtime.getRuntime().availableProcessors(); 
    public MyClass() { 
     int maxThreads = NUM_CORES * 2; 
     this.forkJoinPool = new ForkJoinPool(maxThreads); 
    } 

    public void doStuff() { 
     final int[] toIndex = {0}; 
     forkJoinPool.submit(() -> { 
      List<ForkJoinTask> tasks = new ArrayList<>(); 
      while (toIndex[0] < objects.size()) { 
       toIndex[0] += 20; 
       List<Object> bucket = objects.subList(toIndex[0] - 20, toIndex[0]); 
       ForkJoinTask task = new UpdateAction(bucket); 
       tasks.add(task); 
       task.fork(); 
      } 
      tasks.forEach(ForkJoinTask::join); 
     }).join(); 
    } 

    private class UpdateAction extends RecursiveAction { 

     private List<Object> bucket; 

     private UpdateAction(List<Object> bucket) { 
      this.bucket = bucket; 
     } 

     @Override 
     protected void compute() { 
      // do some calculation 
     } 
    } 
} 
+0

は、ソース(GrepCode)を見ると - 数は、ちょうどすべてのForkJoinPools間で共有され、新しいワーカーが作成されたときにインクリメント一般的なカウンタです。これは、ForkJoinPoolにスレッドがいくつあるかを反映しません。 – Fildor

答えて

1

タスク名の最後の数字は、プールで実際に使用されるスレッドの数とは関係ありません。 ForkJoinPoolクラスのregisterWorkerメソッドを見てみましょう。それは次のようになります:あなたはより良いものをgetPoolSize()リターンをログプールで使用されるスレッドの実際の数を測定したい場合は

final WorkQueue registerWorker(ForkJoinWorkerThread wt) { 
    UncaughtExceptionHandler handler; 
    wt.setDaemon(true);       // configure thread 
    if ((handler = ueh) != null) 
     wt.setUncaughtExceptionHandler(handler); 
    WorkQueue w = new WorkQueue(this, wt); 
    int i = 0;         // assign a pool index 
    int mode = config & MODE_MASK; 
    int rs = lockRunState(); 
    ... 
    // some manipulations with i counter 
    ... 
    wt.setName(workerNamePrefix.concat(Integer.toString(i >>> 1))); 
    return w; 
} 

workerNamePrefix

"ForkJoinPool-" + nextPoolId() + "-worker-" 

に初期化されます。

+0

したがって、forkJoinPoolの並列性が8(4コア* 2)であれば、数千人のワーカーが作成されても、8つしか並列に実行されません。 – mvieghofer

+0

@mvieghoferプールには8つ以上のスレッドが含まれていてもかまいません(すべての参加者がブロックされている場合)。これはForkJoinPool.javaクラスのコメントです: "十分なライブスレッドが存在しない限り、メソッドtryCompensate()は、ブロックされた参加者をブロック解除するまで、予備のスレッドを作成または再アクティブ化します。説明のために –

+0

ありがとう! – mvieghofer

0

あなたは、膨大な数のワーカースレッドについて正しくあります。私はthisを2011年に書きましたが、それは今日もなお適用されます。フレームワークは適切なjoin()を行うことができないので、新しいワーカースレッドまたはストールを作成します。

関連する問題