9 Stimmen

Wie garantiert man die FIFO-Ausführungsreihenfolge in einem ThreadPoolExecutor?

Ich erstelle einen ThreadPoolExecutor mit dieser Codezeile:

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

Dann lasse ich 25 Aufgaben laufen (T01 bis T25), so dass die Situation wie folgt aussieht:

  • 5 derzeit laufende Aufgaben (T01 bis T05)
  • 20 Aufgaben warten in der Warteschlange (T06 bis T25)

Wenn ich eine weitere Aufgabe (T26) einfüge, da die Warteschlange voll ist, erwarte ich, dass die ältere Aufgabe (T06) entfernt wird, um gestartet zu werden (weil MaxPoolSize nicht erreicht ist) und die neue Aufgabe (T26) am Ende der Warteschlange platziert wird.

Wenn die Warteschlange jedoch voll ist und MaxPoolSize nicht erreicht wird, wird die neueste Aufgabe gestartet wird.

Also, ich habe ...

  • 6 derzeit laufende Aufgaben (T01 bis T05 und T26)
  • 20 Aufgaben warten in der Warteschlange (T06 bis T25)

... anstelle von ...

  • 6 derzeit laufende Aufgaben (T01 bis T06)
  • 20 Aufgaben warten in der Warteschlange (T07 bis T26)

Kann ich den ThreadPoolExecutor konfigurieren, um das erwartete Ergebnis zu erhalten? Sollte ich eine andere Klasse verwenden?

Zur Information, Teil des ThreadPoolExecutor-Quellcodes

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

Danke

6voto

Peter Lawrey Punkte 511323

Ich würde die Kerngröße auf das Maximum festlegen. So werden die meisten Pools verwendet, und ich bin mir nicht sicher, wann das in Ihrem Fall der Nachteil wäre, aber Sie würden die Aufgaben in der richtigen Reihenfolge ausgeführt bekommen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X