Threads Thread stirbt aber Objekte in ihm leben weiter?!

headgrowe

Aktives Mitglied
hallo liebe javafreunde,

wie immer sind mir threads nocht nicht so ganz klar ;(

also ich habe einen laufenden thread, welcher gewisse sachen ausführt und objekte erstellt (zb. systemTrays und ein JWindow...)

wenn dieser thread nun einen fehler wirft (exception) dann stirbt er (isAlive == false).
Was nun komisch ist, dass wenn der thread tot ist, dann ist das systemTray und das JWindow immer noch sichtbar und mir ist nicht gelungen dies zu verhindern... mit system.exit(..) ist alles tot, das möchte ich auch nicht, sondern, das der tote thread einfach verschwindet^^ thread.destroy() ist veraltet und funktioniert sowieso nicht... thread.dumpStack geht auch nicht... hab auch das einzige objekt (jBox) (was systemTray und JWindow beinhaltet) auf null gesetzt...und nichts...

also bitte ich auch um hilfe, danke 😀


der zu sterbende thread:
Java:
class JboxThread extends Thread {

		private List<ActionListener> liseners;
		private JBoxController jBox;

		public JboxThread(JBoxController jBox) {
			this.jBox = jBox;
		}

		public void addActionListener(ActionListener l) {
			if (liseners == null)
				liseners = new LinkedList<ActionListener>();
			liseners.add(l);
		}

		@Override
		public void run() {

			try {
				jBox.init();
				System.out.println("updating...");
				while (jBox.syncClient()) {
					System.out.println("update successful");
					Thread.sleep(5000);
					System.out.println("updating...");
				}
				System.out.println("update wasn't successful");
				// starting thread again, afer loading config
				ConfigController
						.addActionListener(new StartingThreadListener());

			} catch (Exception e) {
				e.printStackTrace();
				// startig thread again
				fireDeadThreadEvent();
			}
			jBox = null;
			liseners = null;
			System.out.println("Exiting thread");
		}

		private void fireDeadThreadEvent() {
			if (liseners != null)
				for (ActionListener l : liseners)
					l.actionPerformed(new ActionEvent(this, 0, "Thread died"));
		}

	}


dies ist ein listener aus dem hauptthread, der gestartet wird, wenn eine configDatei geladen ist...
Java:
	private class StartingThreadListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			ConfigController.removeActionListener(this);
			final JboxThread thread = new JboxThread(jBox);
			thread.addActionListener(new StartingThreadListener());
			thread.start();

			new Thread() {
				@Override
				public void run() {
					while (true)
						if (thread.isAlive()) {
							System.out.println("alive");
							try {
								Thread.sleep(5000);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						} else {
							System.out.println("thread died");
							break;
						}
				}
			}.start();
		}
	}

grüße

head
 
Zuletzt bearbeitet:
Hab's nicht ganz nachvollzogen, aber suchst du vielleicht sowas wie
Thread thread = new Thread() { .... }
thread.setDaemon(true);
thread.start();
???
 
jBox = null;
liseners = null;
Ich glaube du erwartest, dass wenn du eine Variable auf null setzt, das Objekt, auf das die Variable zeigt gelöscht wird. Dem ist aber nicht so. Wenn du deine jBox irgendwie beenden willst, braucht dieses Objekt eine Methode wie dispose oder so, die kannst du dann aufrufen.
 
Ein Thread beinhaltet keine Objekte. Er führt nur Anweisungen aus. Stell dir vor ich mal dir ein Bild und gebe es dir. Wenn ich draufgeh hast du es noch immer 😉

Ich glaube du erwartest, dass wenn du eine Variable auf null setzt, das Objekt, auf das die Variable zeigt gelöscht wird. Dem ist aber nicht so.
Doch, klar ist dem so. Es sei denn, das war nicht die letzte Referenz.

@TO Ich verstehe leider nicht ganz was du machen willst... Aber im Falle von GUI-Komponenten bringt dir das mit = null in der Tat nix. Denn deine Box oder was auch immer wird noch immer referenziert - und zwar intern. Und das ist solange der Fall, solange du sie nicht aus der GUI rausnimmst. Methode:
Code:
remove
 
Zuletzt bearbeitet:
Danke für die vielen antworten.

also, als java programmierer muss ich mich schon auf den garbage collector verlassen können, is klar, dass er etwas zeit braucht...😉

also, wenn ich das richtig verstanden habe, muss ich zuerst das ((JWindow) w).dispose(); ausführen, um das fenster zu schließen und das trayIcon entfernen, damit sich mein thread (der eigentlich eh schon tot ist) und die objekte mit denen er gearbeitet hat, auch entfernen..

wenn ich das nun richtig verstanden habe, "überleben" aber auch nur die objekte die vom system auch referenziert werden (GUI) und die restlichen, werden entfernt, da sie keinen pointer mehr auf sich haben.

hmmm, macht soweit sinn 😀

danke

grüße
jacob
 
Wenn du nur [c]((JWindow) w).dispose();[/c] aufrufst, dann hast du immer noch eine Referenz darauf und dieses hat wiederum Referenzen auf weitere Objekte usw.
 
Nicht sofort. Erst wenn der Garbage Collector das nächste läuft und sich den entsprechenden Bereich anschaut.
Ja aber das spielt keine Rolle für's Programm bzw. den Programmierer. Wenn ein Objekt nicht mehr referenziert wird, kommt es im Programm auch nicht mehr vor, egal ob es nun noch im Speicher rumhängt oder nicht. Der TO verwechselt hier glaube ich Speichermodell mit GUI.. Zumindest verstehe ich das so. Ich muss aber sagen ich begreife eh nicht ganz was er löschen will, und was das mit irgendeinem Thread zu tun haben soll
 
Ich wiederhole mich nochmal:
Ich glaube du erwartest, dass wenn du eine Variable auf null setzt, das Objekt, auf das die Variable zeigt gelöscht wird. Dem ist aber nicht so.
Eine Objektvariable in Java ist nur eine Referenz auf das Objekt. Wenn du diese Variable auf null setzt, liegt das Objekt immer noch im Speicher. Wann und ob der Garbage Collector den Speicher freigibt kannst du nicht wirklich festlegen.
 
Und ich wiederhole nochmal:

Wenn ein Objekt nicht mehr referenziert wird, kommt es im Programm auch nicht mehr vor, egal ob es nun noch im Speicher rumhängt oder nicht.

Und damit meine ich nicht nur explizite Referenzen von Variablen des Programmierers, sondern auch intern entstehende Referenzen aus der API. Ein Objekt ist ab dem Zeitpunkt, ab dem es nicht mehr referenziert wird Garbage. Müll bleibt Müll, ob die Abfuhr nun schon da war oder noch kommt, das ist nur für den GC und das Betriebssystem von Relevanz, aber für das Programm existiert dieses Objekt nicht mehr.
 

Zurück
Oben