2016-01-17 7 views
5

Testamentsvollstrecker # newFixedThreadPool:Warum unterschiedliche Queue beim Erstellen von FixedThreadPool und CachedThreadPool verwenden?

public static ExecutorService newFixedThreadPool(int nThreads) { 
    return new ThreadPoolExecutor(nThreads, nThreads, 
            0L, TimeUnit.MILLISECONDS, 
            new LinkedBlockingQueue<Runnable>()); 
} 

Testamentsvollstrecker # newCachedThreadPool:

public static ExecutorService newCachedThreadPool() { 
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 
            60L, TimeUnit.SECONDS, 
            new SynchronousQueue<Runnable>()); 
} 

Warum die beiden Thread verschiedene Queue verwenden? Ich habe Java Doc über LinkedBlockingQueue und SynchronousQueue nachgeschlagen, aber ich weiß immer noch nicht, warum sie hier verwendet werden, Ist die Leistung in Betracht ziehen oder andere?

+0

Ist es ein Duplikat? Es stellt sich nicht die gleiche Frage. Die Antwort kann etwas gemeinsam haben, aber es ist eine andere Frage. –

+0

Grund von verwandter SE-Frage: SynchronousQueue ist eine ganz besondere Art von Warteschlange - sie implementiert einen Rendezvous-Ansatz (Produzent wartet, bis der Konsument bereit ist, der Konsument wartet, bis der Produzent bereit ist) hinter der Schnittstelle von Queue. –

Antwort

0

Die Antwort ist in der Dokumentation der Klasse ThreadPoolExecutor:

  • Queuing
    • Alle {@link Blocking} verwendet werden können
    • eingereichten Aufgaben zu übertragen und halten . Die Verwendung dieser Warteschlange wirkt sich auf die Poolgröße aus: * *
        * *
      • Wenn weniger als corePoolSize-Threads ausgeführt werden, fügt der Executor * immer einen neuen Thread * statt in die Warteschlange ein.
      • * *
      • Wenn corePoolSize oder mehrere Threads ausgeführt werden, zieht der Executor * immer eine Anfrage in die Warteschlange, anstatt einen neuen Thread * hinzuzufügen.
      • * *
      • Wenn eine Anfrage nicht in die Warteschlange gestellt werden kann, wird ein neuer -Thread erstellt, es sei denn * dies würde maximumPoolSize überschreiten, in diesem Fall wird die Aufgabe * abgelehnt.
      • * *
      * * Dort sind drei allgemeine Strategien für die Warteschlange: *
    • Direkte Übergaben. Eine gute Standardauswahl für eine Work * -Warteschlange ist eine {@link SynchronousQueue}, die Aufgaben an Threads * ohne übergibt, andernfalls hält sie. Hier schlägt ein Versuch, eine Aufgabe * in die Warteschlange zu stellen, fehl , wenn keine Threads sofort verfügbar sind, um sie auszuführen, so wird ein * neuer Thread aufgebaut. Diese Richtlinie vermeidet Blockierungen, wenn * die Verarbeitung von Anforderungen mit internen Abhängigkeiten verarbeitet. * Direkte Übergaben erfordern in der Regel unbegrenzte maximumPoolSizes, um die Ablehnung von neu übermittelten Aufgaben zu vermeiden. Dies wiederum erlaubt die * Möglichkeit von grenzenlosen Thread-Wachstum, wenn Befehle im Durchschnitt schneller ankommen als sie verarbeitet werden können * .
    • * *
    • Unbegrenzt Warteschlangen.Bei Verwendung einer unbegrenzten Warteschlange (für * Beispiel eine {@link LinkedBlockingQueue} ohne vordefinierte * Kapazität) werden neue Aufgaben in der Warteschlange warten, wenn alle * corePoolSize-Threads beschäftigt sind. Daher werden nie mehr als corePoolSize * -Threads erstellt. (Und der Wert der maximumPoolSize * hat daher keine Wirkung.) Dies kann geeignet sein, wenn * jede Aufgabe vollständig unabhängig von anderen ist, so dass Aufgaben nicht beeinflussen können * andere Ausführung; zum Beispiel in einem Webseitenserver.* Während dieser Stil von Warteschlangenbildung nützlich sein kann in * transiente Bursts von Anforderungen glätten, gibt es die Möglichkeit der * unbegrenzte Arbeit Warteschlange Wachstum , wenn Befehle weiterhin auf * durchschnittlich schneller als sie können verarbeitet verarbeitet werden.
    • * *
    • Begrenzte Warteschlangen. Eine begrenzte Warteschlange (z. B. eine * {@link ArrayBlockingQueue}) verhindert die Erschöpfung der Ressource , wenn * mit endlichen maximumPoolSizes verwendet wird, kann aber schwieriger sein * zu tunen und zu steuern. Warteschlangengrößen und maximale Poolgrößen können gegeneinander ausgetauscht werden: Die Verwendung großer Warteschlangen und kleiner Pools minimiert CPU-Auslastung, Betriebssystemressourcen und Kontextwechsel Overhead, kann jedoch zu künstlich niedrigem Durchsatz führen. Wenn Tasks häufig blockieren (z. B. wenn sie E/A-gebunden sind), kann ein System * Zeit für weitere Threads einplanen, als Sie andernfalls zulassen. Die Verwendung von kleinen Warteschlangen * erfordert in der Regel größere Poolgrößen, wodurch die CPUs belästigt, * aber möglicherweise eine inakzeptable Planung Overhead auftritt, was ebenfalls den Durchsatz verringert.

die erste Art von Warteschlange sofort auf die verfügbaren Threads eine neue Runnable, die zweite Art es in der Praxis hält senden, wenn alle Fäden beschäftigt sind.

+0

Beide APIS geben unbegrenzte Warteschlangen zurück. –

+0

@ravindra Modifizierte meine Antwort –

Verwandte Themen