Thread mit wait anhalten, wie weiterlaufenlassen?

Status
Nicht offen für weitere Antworten.

MPW

Top Contributor
Moin,

in einem kleinen SnakeClone moechte ich den Thread, der die Schlange bewegt, wenn der Spieler die Pausetaste betaetigt anhalten und wieder fortfahren koennen. Im Prinzip alles kein Problem, aber das weiterlaufen lassen geht bei mir nicht, hier der Code:


KeyListener:
Code:
else if (e.getKeyCode() == KeyEvent.VK_P) {
				threadAnhalten = !threadAnhalten;
				if (!threadAnhalten) {
					tt.notify(); //dies ist Zeile 41, siehe unten
				}
			}

Thread:
Code:
			if (threadAnhalten) {
				synchronized (tt) {
					try {
						tt.wait();
						//tt.notify();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}


Aber immer wenn ich den Thread fortsetzen will, kriege ich diese not-owner-Exception-Geschichte. Beim Anhalten hab ich das ja dadurch geloest, dass sich der Thread selbst anhaelt, aber er kann sich ja nicht selbst fortsetzen...notifyAll klappt auch nicht, hier die Exception:

Code:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException: c
urrent thread not owner
        at java.lang.Object.notify(Native Method)
        at SchlangenPlatz$1.keyPressed(SchlangenPlatz.java:41)
        at java.awt.AWTEventMulticaster.keyPressed(AWTEventMulticaster.java:191)

        at java.awt.AWTEventMulticaster.keyPressed(AWTEventMulticaster.java:191)

        at java.awt.Component.processKeyEvent(Component.java:5446)
        at javax.swing.JComponent.processKeyEvent(JComponent.java:2713)
        at java.awt.Component.processEvent(Component.java:5265)
        at java.awt.Container.processEvent(Container.java:1966)
        at java.awt.Component.dispatchEventImpl(Component.java:3955)
        at java.awt.Container.dispatchEventImpl(Container.java:2024)
        at java.awt.Component.dispatchEvent(Component.java:3803)
        at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.ja
va:1810)
        at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboard
FocusManager.java:672)
        at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeybo
ardFocusManager.java:920)
        at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeybo
ardFocusManager.java:798)
        at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFoc
usManager.java:636)
        at java.awt.Component.dispatchEventImpl(Component.java:3841)
        at java.awt.Container.dispatchEventImpl(Container.java:2024)
        at java.awt.Window.dispatchEventImpl(Window.java:1774)
        at java.awt.Component.dispatchEvent(Component.java:3803)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchTh
read.java:242)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:163)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)

        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)

        at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

Weiss jemannd, wie man sowas realisiert? Ich blicks gerade nicht....


edit: Ein nicht eingefuegt, um die Satzlogik zu korrigieren.
 
ist der notify teil ebenso synchronisiert bzw. auf was synchronisierst du ?
 
MPW hat gesagt.:
Moin,
in einem kleinen SnakeClone moechte ich den Thread, der die Schlange bewegt, wenn der Spieler die Pausetaste betaetigt anhalten und wieder fortfahren koennen. Im Prinzip alles kein Problem, aber das weiterlaufen lassen geht bei mir nicht, hier der Code:

Anstatt einen Thread direkt zu unterbrechen oder weiterlaufen zu lassen, ist es oft besser
daß dies der Thread selbst erledigt indem es ihm über eine gemeinsame Variable mitgeteilt wird,
dann gibts auch keine Probleme mit dem Eigentümer 8)

Im folgenden Beispiel zählt der erste Thread einfach alle halbe Sekunde aufwärts und wird
dreimal darauf hingewiesen zu pausieren.
Code:
public class Wait {
	boolean wait;
	boolean exit;

	void start() {
		wait = false;
		exit = false;

		// starte Thread der zählt
		new Thread(new Runnable() {public void run() {
			int i = 0;
			while (!exit) {
				if (!wait)
					System.out.println(++i);
				try {Thread.sleep(500);} catch (InterruptedException e) {}
			}}}).start();

		// start Thread der den anderen ab und zu warten läßt
		new Thread(new Runnable() {public void run() {
			for (int i=0; i < 3; ++i) {
				// Laß den "Kollegen" etwas zählen
				try {Thread.sleep(3000);} catch (InterruptedException e) {}
				wait = true;
				// Laß den "Kollegen" warten
				try {Thread.sleep(3000);} catch (InterruptedException e) {}
				wait = false;
			}
			exit = true;
		}}).start();
	}

	public static void main(String[] args) {
		new Wait().start();
	}
}

Der zweite Thread dient nur dazu, daß 6-malige Drücken der Pause-Taste zu simulieren weil
ich zu faul bin extra eine GUI drumrum zu basteln. In deinem Fall kannst du den gesamten
2. Thread einfach durch
Code:
threadAnhalten = !threadAnhalten
ersetzen.
 
Hm, ^^das haelt aber nicht den Thread an, sondern laesst ihn nur warten, das ist ja nicht so direkt das, was ich will.


Hab jetzt noch auf tt, das Threadobjekt synchronized und es geht, vielen Dank!
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben