Ich habe ein kleines Problem mit einer Anwendung, die mehrere Java-Threads ausführt. Die Anwendung führt eine Reihe von Arbeits-Threads aus, die kontinuierlich in einer Eingabewarteschlange suchen, und wenn sich Nachrichten in der Warteschlange befinden, ziehen sie sie heraus und verarbeiten sie.
Unter diesen Arbeitsfäden gibt es einen weiteren Überprüfungsthread, der so geplant ist, dass er zu einem festen Zeitpunkt eine Überprüfung durchführt, um zu sehen, ob der Host (auf dem die Anwendung ausgeführt wird) immer noch "in gutem Zustand" ist, um die Anwendung auszuführen. Dieser Thread aktualisiert einen AtomicBoolean
-Wert, der seinerseits vom Arbeitsthread überprüft wird, bevor er beginnt, nachzusehen, ob der Host in Ordnung ist.
Mein Problem ist, dass in Fällen mit hoher CPU-Belastung der Thread, der für die Verifizierung zuständig ist, länger braucht, weil er mit allen anderen Threads konkurrieren muss. Wenn die AtomicBoolean
nach einer bestimmten Zeit nicht aktualisiert wird, wird sie automatisch auf "false" gesetzt, was mir einen fiesen Flaschenhals verursacht.
Meine erste Herangehensweise bestand darin, die Priorität des Verifikations-Threads zu erhöhen, aber wenn ich tiefer in sie eindringe, stellte ich fest, dass dies kein garantiertes Verhalten ist und ein Algorithmus sollte nicht darauf angewiesen sein, dass die Thread-Priorität korrekt funktioniert.
Hat jemand alternative Ideen? Danke!
Anstatt in eine normale Warteschlangendatenstruktur zu schauen, verwenden Sie die LinkedBlockingQueue des java.util.concurrent-Pakets.
Was Sie tun können, ist, einen Pool von Threads auszuführen (Sie könnten den Thread-Pool des Executier-Service verwenden, d. h. eine Anzahl von Workern Ihrer Wahl) und LinkedBlockingQueue.take () ausführen.
Wenn eine Nachricht in der Warteschlange eintrifft, wird sie einem der wartenden Threads zugeführt (ja, take blockiert den Thread, bis etwas mit ihm zu tun hat).
Java-API-Referenz für die Take-Methode der Linked Blocking Queue
HTH.
Ein Ansatz der alten Schule zur Drosselung der Arbeitsrate, der überhaupt keinen Health-Check-Thread verwendet (und so diese Probleme umgeht), ist das Blockieren oder Ablehnen von Anforderungen, die der Warteschlange hinzugefügt werden sollen, wenn die Warteschlange länger als angenommen ist 100. Dies wendet einen dynamischen Gegendruck auf die Clients an, die die Last erzeugen, und verlangsamt sie, wenn die Worker-Threads überladen sind.
Dieser Ansatz wurde der Java 1.5-Bibliothek hinzugefügt, siehe java.util.concurrent.ArrayBlockingQueue. Seine put (o) -Methode blockiert, wenn die Warteschlange voll ist.
Mehr Threads bedeutet keine bessere Leistung. Normalerweise, wenn Sie Dual-Core haben, gibt 2 Threads die beste Leistung, 3 oder mehr beginnt schlechter zu werden. Quad-Core sollte 4 Threads am besten behandeln, usw. Also sei vorsichtig, wie viele Threads du verwendest.
Sie können die anderen Threads nach Ausführung ihrer Arbeit in den Ruhezustand versetzen und anderen Threads erlauben, ihren Teil zu tun. Ich glaube, Thread.yield () wird den aktuellen Thread anhalten, um anderen Threads Zeit zu geben.
Wenn Sie möchten, dass Ihr Thread fortlaufend ausgeführt wird, würde ich vorschlagen, zwei Hauptthreads, Thread A und B, zu erstellen. Verwenden Sie A für den Überprüfungsthread und erstellen Sie von B aus die anderen Threads. Daher erhält Thread A mehr Ausführungszeit.
Scheint, dass Sie Condition-Variablen verwenden müssen. Spähen wird CPU-Zyklen nehmen.
Tags und Links java multithreading thread-priority