Ich habe ein Programm, das Threads (~ 5-150) erzeugt, die eine Reihe von Aufgaben ausführen. Ursprünglich habe ich a verwendet, FixedThreadPool
weil diese ähnliche Frage darauf hindeutete, dass sie besser für längerlebige Aufgaben geeignet sind, und mit meinen sehr begrenzten Kenntnissen über Multithreading habe ich die durchschnittliche Lebensdauer der Threads (mehrere Minuten) als " langlebig " angesehen.
Ich habe jedoch kürzlich die Möglichkeit hinzugefügt, zusätzliche Threads zu erzeugen, wodurch ich über das von mir festgelegte Thread-Limit hinausgehe. Wäre es in diesem Fall besser, die Anzahl der Threads zu erraten und zu erhöhen, die ich zulassen kann, oder zu einem zu wechseln, CachedThreadPool
damit ich keine verschwendeten Threads habe?
Wenn ich sie beide vorab ausprobiere, scheint es keinen Unterschied zu geben, also neige ich dazu, mich CachedThreadPool
nur für die Verschwendung zu entscheiden. Bedeutet die Lebensdauer der Threads jedoch, dass ich stattdessen eine auswählen FixedThreadPool
und mich nur mit den nicht verwendeten Threads befassen sollte? Diese Frage lässt den Eindruck entstehen, dass diese zusätzlichen Themen nicht verschwendet werden, aber ich würde mich über die Klarstellung freuen.
ThreadPoolExecutor
Like erstellenThreadPoolExecutor(0, maximumPoolSize, 60L, TimeUnit.SECONDS, SynchronousQueue())
?Beides
FixedThreadPool
undCachedThreadPool
sind Übel in hoch belasteten Anwendungen.CachedThreadPool
ist gefährlicher alsFixedThreadPool
Wenn Ihre Anwendung stark ausgelastet ist und eine geringe Latenz erfordert, sollten Sie beide Optionen aufgrund der folgenden Nachteile besser entfernen
CachedThreadPool
, dass die Thread-Erstellung außer Kontrolle gerätDa Sie wissen, dass beide Übel sind, tut weniger Böses nichts Gutes. Bevorzugen Sie ThreadPoolExecutor , der eine detaillierte Steuerung vieler Parameter bietet.
beforeExecute(Thread, Runnable)
undafterExecute(Runnable, Throwable)
quelle
Sind Sie sicher, dass Sie verstehen, wie Threads tatsächlich von Ihrem Betriebssystem und der Hardware Ihrer Wahl verarbeitet werden? Wie ordnet Java Threads OS-Threads zu, wie ordnet das Threads CPU-Threads usw. zu? Ich frage, weil das Erstellen von 150 Threads in ONE JRE nur dann sinnvoll ist, wenn Sie massive CPU-Kerne / Threads darunter haben, was höchstwahrscheinlich nicht der Fall ist. Je nach verwendetem Betriebssystem und RAM kann das Erstellen von mehr als n Threads sogar dazu führen, dass Ihre JRE aufgrund von OOM-Fehlern beendet wird. Sie sollten also wirklich zwischen Threads und der von diesen Threads auszuführenden Arbeit unterscheiden, wie viele Arbeiten Sie überhaupt verarbeiten können usw.
Und das ist das Problem mit CachedThreadPool: Es ist nicht sinnvoll, lange laufende Arbeiten in Threads in die Warteschlange zu stellen, die tatsächlich nicht ausgeführt werden können, da nur 2 CPU-Kerne diese Threads verarbeiten können. Wenn Sie am Ende 150 geplante Threads haben, können Sie viel unnötigen Overhead für die Scheduler verursachen, die in Java und im Betriebssystem verwendet werden, um sie gleichzeitig zu verarbeiten. Dies ist einfach unmöglich, wenn Sie nur 2 CPU-Kerne haben, es sei denn, Ihre Threads warten die ganze Zeit auf E / A oder ähnliches. Aber selbst in diesem Fall würden viele Threads eine Menge E / A erzeugen ...
Und dieses Problem tritt bei FixedThreadPool nicht auf, das mit z. B. 2 + n Threads erstellt wurde, wobei n natürlich vernünftig niedrig ist, da damit Hardware- und Betriebssystemressourcen mit weitaus weniger Aufwand für die Verwaltung von Threads verwendet werden, die ohnehin nicht ausgeführt werden können.
quelle