Bitte helfen Sie mir, den Grund für Thread-Leck in dem folgenden Code zu finden. Die TestThread
ruft keine Garbage Collected ab, nachdem run() abgeschlossen wurde (bestätigt durch die consoled print-Anweisung) und die Hauptmethode beendet wurde (verifiziert von print statement und profiler tool).Warum UserThread, das mit ScheduleExecutorService ausgeführt wird, keinen Müll sammelt
Die TestThread
wird jedoch Müll gesammelt, wenn es als Daemon Thread festgelegt ist, d. H. t.setDaemon(true)
. Der folgende Code ist nur ein Beispielcode, der das Problem in meiner Anwendung veranschaulicht. Ich versuche, eine bereits vorhandene Planungsklasse zu verwenden (die von jemand anderem mit ScheduledExecutorService
entworfen wurde). Ich merke, dass, wenn ich mehrere Runnable
s mit der Klasse einplane, die erstellten Threads niemals Müll gesammelt bekommen.
public class ThreadTest {
static void runThreadWithExecutor() {
final String name = "TestThread";
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor(
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, name);
t.setDaemon(false);
return t;
}
});
ses.schedule(new Runnable() {
@Override
public void run() {
System.out.println("entered " + name);
System.out.println("exiting " + name);
}},
2,
TimeUnit.SECONDS);
}
public static void main(String[] args) throws InterruptedException {
System.out.println("entered main");
runThreadWithExecutor();
Thread.sleep(5000);
System.out.println("exiting main");
}
}
Gute info John. Eine Verbesserung. 'shutdown()' beendet nicht alle Threads im Thread-Pool, bis alle Jobs fertig sind. – Gray
@Gray Guter Punkt –
Danke Jungs. Obwohl ich dies zunächst als meine akzeptierte Antwort ausgewählt habe, habe ich später Greys gewählt, weil diese Antwort ohne Gray nicht selbsterklärend ist. Diese Antwort gab mir jedoch die vollständige Erklärung, um den Code mit Sicherheit zu ändern :) und es funktioniert! – Kes115