Ich habe eine Java-Anwendung, die nicht endet. Die Hauptmethode wird beendet, die Threads bleiben jedoch aktiv und die Anwendung wird nicht beendet. Die Sache ist, es scheint keine Monitor-Sperren / Wartezeiten zu geben, also kann ich nicht sehen, warum es nicht aufhört. Laut Eclipse habe ich zwei Nicht-Daemon-Threads. Einer ist mit [DestroyJavaVM] gekennzeichnet (sieht hoffnungsvoll aus!) Und der andere scheint in Unsafe.park(boolean, long)
blockiert zu sein. Wie / wo soll ich das untersuchen?
Der abgekürzte Stacktrace des zweiten Threads ist:
%Vor% Sie müssen eines von zwei Dingen tun, um Ihren ExecutorService
thread zu beenden:
ThreadFactory
ein, die Daemon-Threads erstellt (die ThreadFactoryBuilder
-Klasse von Guava macht dies möglich) einfacher.) shutdown()
auf Ihrem ExecutorService
als Teil des Anwendungs-Shutdown auf (z. B. am Ende Ihrer main
-Methode.) Ich bin mir nicht sicher, wie groß die Anwendung ist, aber ich würde alle erstellten Threads überprüfen und sicherstellen, dass ihre Ausführungsmethoden sauber beendet werden, wenn die Anwendung ausgeführt wird. Irgendwo, innerhalb eines Threads, haben Sie möglicherweise Code in den folgenden Zeilen:
%Vor% Unsafe.park
wird trotz des erschreckend klingenden Namens normalerweise von allen Arten von blockierenden Aufrufen verwendet (besonders von denen im neuen (ish) java.util.concurrent
-Paket).
Wenn Sie sich ein paar Frames weiter unten im Stack ansehen, sehen Sie etwas wie java.util.concurrent.LinkedBlockingQueue.take
(dh eine JDK-Bibliotheksklasse) gefolgt von etwas wie com.example.myapp.MyClass.getNextJob
(dh Ihre Klasse, die die Bibliotheksklasse verwendet) / p>
Wenn ich eine Vermutung riskieren müsste, würde ich sagen, dass Sie irgendeine Art von Anruf machen, der für immer blockiert - und wenn dann nichts mehr zurückkommt, sitzt dieser Thread einfach dort und wartet auf den "nächsten" Gegenstand. Sie könnten dies lösen, indem Sie eine Art "Fertig" -Flag setzen und dann entweder den wartenden Thread unterbrechen oder dem blockierenden Anruf ein Timeout geben, um ihn dazu zu bringen, das Flag zu prüfen. Abhängig von deinem Code könnte eine dieser beiden oder eine Alternative machbar sein, aber hoffentlich ist das genug, um dich anzufangen.
Bearbeiten: Nachdem der Stacktrace angezeigt wurde, Finnw ist richtig , dass Sie Ihren Executor-Dienst herunterfahren müssen.
Ihre Aufgabe ist blockiert und wartet auf Daten aus der Warteschlange. Take hat kein Timeout.
Pflegen Sie einen Verweis auf Ihren Aufgaben-Thread, wenn er erstellt wird. Rufen Sie beim Herunterfahren die Interrupt-Methode für den Thread auf. Möglicherweise müssen Sie auch die Arbeitsverarbeitungsschleife ändern, die zum Beenden aufgerufen wird, wenn InterruptedException abgefangen wird.
Tags und Links eclipse java multithreading