Was geschieht mit Java-Klasse, die aus ArrayList entfernt wird?

Methusalem

Mitglied
Hallo,
Ich habe in meinem Projekt eine umfangreiche ArrayList, wo Elemente ständig hinzugefügt und entfernt werden. Dabei ist mir aufgefallen (was ich vermutlich längst wissen müsste?), dass ein laufender javax.swing.Timer nicht aufhört seine Funktion aufzurufen, sowie das Objekt welches diesen Timer in seiner Klasse enthält aus der ArrayList entfernt wurde (mittels <NameDerArrayList>.remove(<PositionDesObjekts>)).
Ich wäre mit meinem Grundwissen davon ausgegangen, dass ein gelöschtes Objekt auch nicht mehr aufrufbar sein dürfte, und es sich auch selbst nicht mehr aufrufen dürfte (bzw. eine enthaltene Funktion). Kann ich das Objekt anderweitig entfernen, so dass es nicht fortwährend im Hintergrund läuft? Oder muss ich das so hinnehmen, ist das so wie es sein sollte bei OOP, und muss ich demnach den Timer manuell anhalten, bevor ich das Objekt entferne?
 
Nur weil der Timer nicht mehr erreichbar ist, läuft er trotzdem in einem eigenen Thread, bis du entweder die JVM schließt oder in manuell stoppst.
 
Nur weil der Timer nicht mehr erreichbar ist, läuft er trotzdem in einem eigenen Thread, bis du entweder die JVM schließt oder in manuell stoppst.

Genau genommen müßte der GC ihn aber trotzdem weghauen, so er denn die Zeit dafür findet. Übrigens genau einer der Gründe warum GC nicht das Gelbe vom Ei ist. Man weiß einfach nicht was im Speicher mit seinen Objekten passiert. Da ist es besser man räumt gleich alles selber auf.

Gruß

Claus
 
Dann stoppe ich ihn halt manuell, daran soll es nicht liegen, das ist keine große Sache. Ich hab mich nur sehr über dieses Verhalten gewundert, wäre nicht so zu erwarten gewesen...
 
Ja, du musst ihn manuell stoppen. Wenn du keine Referenz mehr darauf hast, kannst du das nicht mehr und er läuft ggf. ewig weiter oder hört irgendwann zufällig auf.

Wenn du ihn stoppst und alle Referenzen darauf nullst (= aus der ArrayList entfernst) wird der Speicherplatz früher oder später vom GC wieder freigegeben. Darum musst du dir keine Gedanken machen, einer der Vorteile von GC.
 
Eigentlich verhindert der Thread im Hintergrund, dass sich die JVM beendet. Außer natürlich es ist ein Daemon-Thread.
Woher sollte der GC wissen, ob nicht gepollt wird oder er irgendwelche Ereignisse emittiert?

Stimmt auch wieder. Aber ich glaube schon das wenn der Main Thread einer App beendet wird dann werden auch alle Threads die daraus gestartet wurden beendet oder?

Gruß

Claus
 
Dem Thread ist das natürlich egal aber der JVM nicht. Die killt gnadenlos alles was innerhalb dieser Applikation gestartet wurde
Das glaube ich nicht. Ich habs deshalb getestet:

Java:
class Test {
    public static void main(String... args) {
        new Thread(() -> {
            for (int i = 0;i < 100;i++) {
                try { Thread.sleep(100); } catch (Exception ex) {}
                System.out.println("Sub-Thread");
            }
        }).start();
     
        System.out.println("Der Main-Thread endet jetzt.");
    }
}

Ausgabe wie erwartet:

Code:
Der Main-Thread endet jetzt.
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
....

Wohingegen:
Java:
class Test {
    public static void main(String... args) {
        Thread t = new Thread(() -> {
            for (int i = 0;i < 100;i++) {
                try { Thread.sleep(100); } catch (Exception ex) {}
                System.out.println("Sub-Thread");
            }
        });
       
        t.setDaemon(true);
        t.start();
       
        try { Thread.sleep(1000); } catch (Exception ex) {}
       
        System.out.println("Der Main-Thread endet jetzt.");
    }
}

dashier ausgibt:

Code:
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Sub-Thread
Der Main-Thread endet jetzt.
 

Zurück
Oben