9

次のコード行で ThreadPoolExecutor を作成します。

private ExecutorService executor = new ThreadPoolExecutor(5, 10, 120, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(20, true));

次に、25 のタスク (T01 から T25) を実行するので、状況は次のようになります。

  • 現在実行中の 5 つのタスク (T01 ~ T05)
  • キューで待機中の 20 タスク (T06 ~ T25)

もう 1 つのタスク (T26) を配置すると、キューがいっぱいになるため、古いタスク (T06) が削除されて起動されると予想され (MaxPoolSize に達していないため)、新しいタスク (T26) が最後に配置されます。待ち行列。

しかし実際には、Queue がいっぱいで MaxPoolSize に達していない場合、最新のタスクが開始されます。

ので、私は持っています ...

  • 現在実行中の 6 つのタスク (T01 ~ T05 および T26)
  • キューで待機中の 20 タスク (T06 ~ T25)

... それ以外の ...

  • 現在実行中の 6 つのタスク (T01 ~ T06)
  • キューで待機中の 20 タスク (T07 ~ T26)

期待される結果を得るために ThreadPoolExecutor を構成できますか? 別のクラスを使用する必要がありますか?

詳細については、ThreadPoolExecutor ソース コードの一部

public void execute(Runnable command) {
    if (command == null)
        throw new NullPointerException();
    if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
        if (runState == RUNNING && workQueue.offer(command)) {
            if (runState != RUNNING || poolSize == 0)
                ensureQueuedTaskHandled(command);
        }
        else if (!addIfUnderMaximumPoolSize(command))
            reject(command); // is shutdown or saturated
    }
}


private boolean addIfUnderMaximumPoolSize(Runnable firstTask) {
    Thread t = null;
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        if (poolSize < maximumPoolSize && runState == RUNNING)
            t = addThread(firstTask);
    } finally {
        mainLock.unlock();
    }
    if (t == null)
        return false;
    t.start();
    return true;
}

ありがとう

4

1 に答える 1

6

コアサイズを最大に等しくします。これがほとんどのプールの使用方法であり、あなたのケースでいつマイナス面になるかはわかりませんが、タスクを順番に実行します。

于 2010-12-13T16:51:40.513 に答える