# thread warten lassen



## Fellkneul (3. Aug 2010)

hallo,

ich muss von einem anderen Thread (als den AWT-Thread) aus ein JFrame abschießen. Dazu habe ich folgendes geschrieben:


```
package fl.client.gfx.util;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Destroyer
{
	private static boolean isDestroyed;
	
	public static void destroy(final JFrame frame)
	{
		isDestroyed = false;
		
		Runnable disposeFrame = new Runnable()
		{
			@Override
			public void run()
			{
				frame.dispose();
				isDestroyed = true;
			}
		};
		
		SwingUtilities.invokeLater(disposeFrame);
		
		Object waiter = new Object();
		
		synchronized(waiter)
		{
			while(!isDestroyed)
			{
				try
				{
					waiter.wait(10);
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		}
	}
}
```

Das funktioniert auch ganz gut. Ich weiß jedoch, dass es nicht die eleganteste Weise ist, einen Thread in einer while mit Object.wait(long timeout); warten zu lassen bis die Bedingung erfüllt ist.

Ich hab versucht statt waiter.wait(long timeout); einfach waiter.wait(); zu verwenden und dann in der Runnable nach dem schließen des Fensters waiter.notify(); aufzurufen. Dann krieg ich folgende Exception:

java.lang.IllegalMonitorStateException
	at java.lang.Object.notify(Native Method)
	at fl.client.gfx.util.Destroyer$1.run(Destroyer.java:23)


```
package fl.client.gfx.util;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Destroyer
{
	private static boolean isDestroyed;
	
	
	public static void destroy(final JFrame frame)
	{
		final Object waiter = new Object();
		isDestroyed = false;
		
		Runnable disposeFrame = new Runnable()
		{
			@Override
			public void run()
			{
				frame.dispose();
				isDestroyed = true;
				waiter.notify();
			}
		};
		
		SwingUtilities.invokeLater(disposeFrame);
		
		
		
		synchronized(waiter)
		{
			while(!isDestroyed)
			{
				try
				{
					waiter.wait();
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		}
	}
}
```

Ich hab keine Ahnung warum. Kann mir jemand sagen, was ich da tun kann und mir nochmal genauer erklären:

Warum dieser Fehler entsteht?
Was eigentlich dieser Block synchronized da tut? (Ich weis, dass er dahin muss, aber genau hab ich keine Ahnung was synchronized Methods etc. eigentlich sind.)
Warum das mit dem waiter.wait(long timeout) nicht so ne gute Variante ist. Immerhin tut er dasselbe und rechnet auch nicht wirklich viel mehr, oder?

vielen Dank im Vorraus,
Fellkneul


----------



## Niki (3. Aug 2010)

du musst beim notify auch auf das gleiche objekt synchronisieren (also auf waiter)


----------



## SlaterB (3. Aug 2010)

ganz kurz: beim notify auch synchronized drumherum, wie du es beim wait hast,
kann man aus Symmetriegründen erkennen, aus der Fehlermeldung nicht unbedingt, aber ab jetzt merken 

lange Erklärungen können nicht so gut sein, wie es im Lehrbüchern sauber aufgeschrieben ist, z.B.:
Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 11 Threads und nebenläufige Programmierung

ohne so ein Kapitel gelesen zu haben mit Threads, wait und notify zu hantieren..

-----

zur Info, noch kürzer zum Warten ist generell einfach nur
thread.join();
aber hier hast du keinen Thread bzw. der AWT-Thread wird nicht beendet nachdem das eine Runnable bearbeitet ist,
insofern ist wait/ notity schon recht gut


----------

