0

私は自分のmultithreadingプログラムでスレッドプールユーティリティを書いています。次のメソッドが正しいことを検証する必要があります。それらは正しい値を返しますか。サイズが1のaLinkedBlockingQueueを使用しています。また、java docを参照すると、「メソッドはおおよその数のフレーズを返す」と常に表示されます。ですから、以下の条件が正しいとは思えません。

public boolean isPoolIdle() {
    return myThreadPool.getActiveCount() == 0;
}

public int getAcceptableTaskCount() {
    //initially poolSize is 0 ( after pool executes something it started to change )
    if (myThreadPool.getPoolSize() == 0) {
        return myThreadPool.getCorePoolSize() - myThreadPool.getActiveCount();
    }
    return myThreadPool.getPoolSize() - myThreadPool.getActiveCount();
}

public boolean isPoolReadyToAcceptTasks(){
    return myThreadPool.getActiveCount()<myThreadPool.getCorePoolSize();
}

あなたの考えや提案を教えてください。

アップデート

興味深いのは、プールが私に3つのスレッドを返す場合、getAcceptableTaskCountメソッドから3つのスレッドが利用可能であり、3つのタスクをプールに渡すと、1つのタスクが拒否され、によって処理されることがありRejectedExecutionHandlerます。時々、プールは私が渡したすべてのタスクを処理します。使用可能なスレッド数に応じてタスクを渡しているのに、なぜプールがタスクを拒否するのか疑問に思っています。

---------灰色の答えの実装---

class MyTask implements Runnable {

@Override
public void run() {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("exec");
}

}

@Test
public void testTPool(){

    ExecutorService pool = Executors.newFixedThreadPool(5);

    List<Future<MyTask>> list = new ArrayList<Future<MyTask>>();

    for (int i = 0; i < 5; i++) {
        MyTask t = new MyTask();
        list.add(pool.submit(t, t));
    }

    for (int i = 0; i < list.size(); i++) {

        Future<MyTask> t = list.get(i);

        System.out.println("Result -"+t.isDone());

        MyTask m = new MyTask();

        list.add(pool.submit(m,m));
    }
}

これはResult -falseコンソールに出力され、タスクが完了していないことを意味します。

4

1 に答える 1

0

あなたのコメントから:

プールがアイドル状態であるか、プールがタスクを受け入れることができるかを知る必要があります。プールが受け入れることができる場合、プール内の空きスレッドの量を知る必要があります。5 の場合、5 つのタスクをプールに送信して処理を行います。

プール会計を自分で行うべきではないと思います。スレッドプールを使用する場合Executors.newFixedThreadPool(5)、必要な数のタスクを送信でき、5 つのスレッドでのみ実行されます。

そのため、ベクターから最初の 5 つのタスクを取得し、それらをプールに割り当てます。ベクター内の他のタスクは、別のサイクルから更新/削除される可能性があるため無視します。

なるほど、分かりました。ジョブをプリロードせずに並列化を最大化したいですか? 次の擬似コードのようなものが機能すると思います。

  int numThreads = 5;
  ExecutorService threadPool = Executors.newFixedThreadPool(numThreads);
  List<Future<MyJob>> futures = new ArrayList<Future<MyJob>>();
  // submit the initial jobs
  for (int i = 0; i < numThreads; i++) {
      MyJob myJob = getNextBestJob();
      futures.add(threadPool.submit(myJob, myJob));
  }
  // the list is growing so we use for i
  for (int i = 0; i < futures.size(); i++) {
      // wait for a job to finish
      MyJob myJob = futures.get(i);
      // process the job somehow
      // get the next best job now that the previous one finished
      MyJob nextJob = getNextBestJob();
      if (nextJob != null) {
         // submit the next job unless we are done
         futures.add(threadPool.submit(myJob, myJob));
      }
  }

ただし、スレッド数がどのように変化するかはよくわかりません。質問を編集して詳細を追加していただければ、回答を微調整できます。

于 2012-05-01T13:45:53.590 に答える