Thread-/ Simulations- Problem

Chris42

Mitglied
Hallo Leute,
Ich hab Probleme damit die Ausführungsgeschwindigkeit einer Simulation zu steuern, dazu erst einmal ein paar Infos.

Momentan muss ich für die Uni den Hamster Simulator nachprogrammieren, dessen wichtigsten Bestandteile sind ein Editor in dem man neue Befehle für den Hamster in Java programmieren kann und ein JPanel indem der Hamster visuell in einer 2D- Welt dargestellt wird.
In dem JPanel wird der Hamster und sein Territorium dargestellt. Diese beiden Klassen bilden auch das Model.
Der Hamster ist von einer Klasse Actor abgeleitet und hat dementsprechend schon einen Befehlssatz. Man kann den selbstgeschriebenen Code im Editor compilieren und dann wird der Hamster durch einen neuen Hamster ersetzt, dieser besitzt dann die neuen Methoden sowie die Methoden des Actors.

Soweit so gut, jetzt möchte das man eine Simulation starten kann (start, pause, stop, JSlider für die Ausführungsgeschwindigkeit). Die Simulation soll über Threads realisiert werden.

Dazu habe ich einen Simulations_Manager indem geschaut wird welcher der Buttons gedrückt wurde und indem geprüft wird ob der Wert des JSliders verändert wurde.

Java:
public class SimulationManager implements ActionListener {
	JToggleButton play;
	JToggleButton pause;
	JToggleButton stop;
	
	boolean running;
	boolean paused;
	
	Simulation simulation;

	public SimulationManager(JToggleButton play, JToggleButton pauseButton,
			JToggleButton stopButton, Simulation simulation) {
		this.play = play;
		this.pause = pauseButton;
		this.stop = stopButton;
		this.simulation = simulation;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == this.play) {
			this.simulation.startSimulation();
		} else if (e.getSource() == this.stop) {
			this.simulation.stopSimulation();
		} else if (e.getSource() == this.pause) {
			this.simulation.pauseSimulation();
		}
	}
}

Wenn der play- Button gedrückt wird soll die Simulation gestartet werden, hier liegt mein Problem:
Es soll nämlich die Main- Methode des momentan aktiven Actors/Hamsters ausgeführt werden, das habe ich soweit auch hinbekommen, allerdings habe ich keine Möglichkeit gefunden wie ich wärend der Ausführung der Main- Methode die Ausführungsgeschwindigkeit anpassen kann.
Mir ist klar das dies mit Thread.sleep(sleepTime) passieren sollte, allerdings wird die Main- Methode direkt als ganzes ausgeführt, ich hätte das aber gerne so, das die Main- Methode quasi Schritt für Schritt ausgeführt wird.

Java:
public class Simulation extends Thread implements Runnable, Observer {

	// volatile Thread thread;
	Territorium terri;
	// TODO Schieberegler für Geschwindigkeit
	volatile int sleepTime;

	public Simulation(Territorium territorium) {
		this.terri = territorium;
		// this.thread = new Thread();
	}

	@Override
	public void run() {
		Class<?> clas = this.terri.getActor().getClass();
		try {
			Method method = clas.getMethod("main", null);
			String[] params = null;
			try {
				method.invoke(this.terri.getActor(), params);
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
			        e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (NoSuchMethodException e) {
			 // TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void startSimulation() {
		this.run();
	}

	public void stopSimulation() {
		this.stop();
	 }

	public void pauseSimulation() {
		 this.interrupt();
	}

	 @Override
	public void update(Observable o, Object arg) {
		if(!(this == null)) {
			 try {
				this.sleep(sleepTime*100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}
	
	public void setSleeptime(int fps) {
		this.sleepTime = fps;
	}
}

Jetzt ist meine Frage ob es überhaupt möglich ist die Main- Methode Schritt für Schritt auszuführen, oder wie man das sonst realisieren könnte.
Ich hatte noch gehofft das man das Warten sonst in der update() Methode realisieren kann aber da fehlt mir auch der Ansatz.

Würde mich freuen wenn mir jemand einen Schubs in die richtige Richtung geben kann oder sonst einen Ansatz hat wie das Problem sonst zu lösen ist.

Gruß Chris
 

InfectedBytes

Top Contributor
ich bin mir nicht ganz sicher ob ich dein problem richtig verstanden habe, aber wieso rufst du beim ändern des sliders nicht einfach simulation.setSleepTime(...) auf?
 

Chris42

Mitglied
Hi InfectedBytes,

über simulation.setSleepTime(...); kann ich ein delay einbauen das ist richtig. Habe ich auch schon getan, hier ist mal die Sliderklasse:

Java:
package simulation.controller;

import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class SliderListener implements ChangeListener {

	Simulation sim;
	int fps;

	public SliderListener(Simulation simulation) {
		this.sim = simulation;
		this.fps = 0;
	}

	@Override
	public void stateChanged(ChangeEvent e) {
		JSlider source = (JSlider) e.getSource();

		fps = (int) source.getValue();

		this.sim.setSleeptime(fps*10);
	}
}

Beim starten der Simulation ist die Verzögerung dann auch da, nur vor dem Aufruf der main- Methode. Also wird die gesamte main()- Methode des aktuellen Actors ausgeführt. Zur Veranschaulichung mal ein kleines Beispiels.

Angenommen der Benutzer schreibt eine main()- Methode für den Actor die folgendermaßen aussieht:

Java:
void main() {
    while(vornFrei()) {
        vor();
    }
}

(Der Actor verfügt immer über die Methoden vornFrei, vor, nachLinksDrehen, prüfenObEineMauerDenWegVersperrt, etwasEinsammeln, etwasRauswerfen)

Dann würde soabld ich die Simulation starte, dem Slider entsprechend gewartet werden und dann die main()- Methode ausgeführt werden und der Actor würde direkt am Ende der Karte stehen.
Ich würde das aber gerne so haben, das die View, also das Panel nach jedem Aufruf von vor(); neu gezeichnet wird.

Ich bräuchte also einen Mechanismus dafür das die main- Methode nach jedem Methodenaufruf der in ihr geschieht erst einmal das repaint des Panels aufruft, dann wieder einen Methodenaufruf macht usw (Also müsste theoretisch alles was in der main()- Methode ist Schritt für Schritt ausgeführt werden).
Aber ich glaube über Reflection kann man nur die gesamte main- Methode ausführen oder?
 

InfectedBytes

Top Contributor
du könntest in jeder Hamstermethode repaint aufrufen.
Java:
public void vor() {
//vorwärts gehen
repaint();
}
Im Grunde kannst du dort auch ein sleep einbauen, damit alles langsamer abläuft.
 

Chris42

Mitglied
Ich sollte vielleicht hinzufügen das ich mit dem Observer- Pattern arbeite.
Das Model meines Projektes besteht aus den Klassen Actor und Territorium. Beide erben von der Klasse Observable.
Das Territorium_Panel ist meine View und implementiert Observer.

Jede Methode die etwas an der View verändert ruft die Methoden setChanged(); und notifyObservers(); auf.
Wird dann nicht automatisch die überschriebene Methode update(); des Territorium_Panels aufgerufen?

Demnach müsste ich die Verzögerung durch den Slider in der update()- Methode des Territorium_Panels durchführen oder?
 

InfectedBytes

Top Contributor
wenn du das sleep in der update methode machst, solltest du dir im Klaren sein, dass jede Änderung des Models zu einem sleep führt! d.h. wenn du ein reset durchführst und die listener aufgerufen werden, dann wird auch sleep ausgeführt.

Daher würde ich das sleep lieber direkt in die Methoden vor() etc. schreiben, da diese ja nur innderhalb des Simulationsthread aufgerufen werden
 

Chris42

Mitglied
Ah das habe ich nicht bedacht, hast natürlich recht. Ich werde die Methoden mal anpassen und meld mich dann nochmal falls es Probleme gibt.
Bis hierhin erstmal vielen Dank für deine Hilfe :)
 

Chris42

Mitglied
Funktioniert leider nicht.
Habe jetzt in der vor()- Methode das sleep() eingebaut.

Wenn ich über Reflection einmal die vor()- Methode aufrufe funktioniert das super. Aber wenn ich die Simulation starte und die main()- Methode aufgerufen wird, dann schläft der Thread x*sleeptime (x sind die Anzahl an vor()- Aufrufen die der Actor insgesamt machen würde) und dann springt der Actor an die Stelle wo er nach dem durchlaufen der main()- Methode wäre.
 
Zuletzt bearbeitet:

InfectedBytes

Top Contributor
du hast den Thread falsch verwendet!
du rufst die Methode startSimulation auf, welche selbst die run methode aufruft, dadurch geschieht aber alles im gleichen Thread.
du musst den Thread mit der start-Methode starten. Also einfach direkt simulation.start() dadurch wird dann die run methode im eigenen Thread ausgeführt.

Ansonsten kann es nicht schaden mal zu schreiben wie denn deine vor methode aussieht.
 

Chris42

Mitglied
Ich habe das mit den Threads echt noch nicht begriffen glaube ich..

Also im SliderListener setze ich die sleepTime je nach Sliderstufe. Momentan in der Actorklasse:
Java:
package simulation.controller;

import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class SliderListener implements ChangeListener {

	Simulation sim;
	int fps;

	public SliderListener(Simulation simulation) {
		this.sim = simulation;
	}

	@Override
	public void stateChanged(ChangeEvent e) {
		JSlider source = (JSlider) e.getSource();
		fps = (int) source.getValue();
		this.sim.terri.getActor().setSleepTime(fps * 100);
		// this.sim.setSleeptime(fps*100);
	}
}

In dem SimulationManager soll ich jetzt den Thread starten richtig? Dann sieht das folgendermaßen aus:
Java:
package simulation.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JToggleButton;

import simulation.model.Territorium;

public class SimulationManager implements ActionListener {
	JToggleButton play;
	JToggleButton pause;
	JToggleButton stop;
	
	Simulation simulation;

	public SimulationManager(JToggleButton play, JToggleButton pauseButton,
			JToggleButton stopButton, Simulation simulation) {
		this.play = play;
		this.pause = pauseButton;
		this.stop = stopButton;
		this.simulation = simulation;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == this.play) {
			this.simulation.start();
		} else if (e.getSource() == this.stop) {
			this.simulation.stopSimulation();
		} else if (e.getSource() == this.pause) {
			this.simulation.pauseSimulation();
		}
	}
}

Die Threadklasse Simulation sieht dann so aus:
Java:
package simulation.controller;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Observable;
import java.util.Observer;

import simulation.model.Actor;
import simulation.model.Territorium;
import exception.EndException;

public class Simulation extends Thread implements Runnable, Observer {

	public Thread thread;
	Territorium terri;
	boolean pause = false;
	public int sleepTime;

	public Simulation(Territorium territorium) {
		this.terri = territorium;
		this.thread = new Thread();
	}

	@Override
	public void run() {
		Class<?> clas = this.terri.getActor().getClass();
		try {
			Method method = clas.getMethod("main", null);
			String[] params = null;
			try {
				method.invoke(this.terri.getActor(), params);
				synchronized (this) {
					while (this.pause) {
						try {
							this.thread.wait();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void startSimulation() {
		if (this.thread == null) {
			this.thread = new Thread(this);
			this.thread.start();
		}
	}

	public void stopSimulation() {
		this.thread.stop();
	}

	public void pauseSimulation() {
		if (this.pause) {
			this.pause = false;
		} else {
			this.pause = true;
		}
	}

	@Override
	public void update(Observable o, Object arg) {
		if (this.thread == null) {
			try {
				throw new EndException();
			} catch (EndException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	// public void setSleeptime(int sleepTime) {
	// this.sleepTime = sleepTime;
	// }
}

Hier ist die move()- Methode der Actorklasse, für den Fall das der Actor nach Norden schaut.
Java:
public void move() {
		synchronized (this.territorium) {

			boolean hadCorn = this.territorium.getHadCorn();

			try {
				switch (viewingDirection) {
				case (FACE_TO_NORTH):
					if (!this.territorium.nextIsWall(this.actY, this.actX)) {
						if (this.territorium.nextHasCorn(this.actY, this.actX)) {
							this.territorium.setHadCorn(true);
						} else {
							this.territorium.setHadCorn(false);
						}
						this.actY -= 1;
						territorium.tiles[this.actY][this.actX] = ACTOR_AT_TILE;
						if (hadCorn) {
							territorium.setCorn(actY + 1, actX);
						} else {
							territorium.clearPosition(actY + 1, actX);
						}
						break;
					} else {
						try {
							throw new DeadException();
						} catch (DeadException e) {

						}
					}
					try {
						Simulation.sleep(this.sleepTime);
					} catch (InterruptedException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					break;
                                // die anderen Fälle...
                                } //Switch Ende.
                         	
                                this.setChanged();
			        this.notifyObservers();

Das Problem bleibt aber weiterhin bestehen, die main()- Methode wird komplett bearbeitet und dann kommt das neuzeichnen der View.
 

Chris42

Mitglied
Ach f... hab den Fehler gefunden, ich musste das sleep natürlich vor dem break; ausführen.....

Java:
try {
				switch (viewingDirection) {
				case (FACE_TO_NORTH):
					if (!this.territorium.nextIsWall(this.actY, this.actX)) {
						if (this.territorium.nextHasCorn(this.actY, this.actX)) {
							this.territorium.setHadCorn(true);
						} else {
							this.territorium.setHadCorn(false);
						}
						this.actY -= 1;
						territorium.tiles[this.actY][this.actX] = ACTOR_AT_TILE;
						if (hadCorn) {
							territorium.setCorn(actY + 1, actX);
						} else {
							territorium.clearPosition(actY + 1, actX);
						}
						try {
							Simulation.sleep(this.sleepTime);
						} catch (InterruptedException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
						break;
					} else {
						try {
							throw new DeadException();
						} catch (DeadException e) {

						}
					}
					
					break;
                          } // End


Dann nochmal besten Dank für deine Zeit und Mühen, funktioniert jetzt 100%ig :)
 
Zuletzt bearbeitet:

InfectedBytes

Top Contributor
deine Thread klasse sieht wirklich ziemlich durcheinander, insbesondere deine startSimulation methode ist ziemlich...merkwürdig^^
hier einmal ein ganz kurzes beispiel wie du threads verwendest:

Java:
public class MyThread extends Thread {
  public void run(){
    //hier kommt deine logik rein, welche parallel zu dem eigentlich programm laufen soll
    //z.b. eben der Aufruf deiner Hamster-Main
  }
}

dort wo du den Thread starten willst:
Java:
//...
MyThread thread = new MyThread();
thread.start();

In deiner Threadklasse erzeugst in der startSimulation einen neuen thread welchen du startest, anstatt eben den thread selbst zu starten

p.s. schön das dein problem gelöst wurde^^
 
Zuletzt bearbeitet:

Chris42

Mitglied
Okay, hab meine Klassen mal etwas angepasst. Arbeite jetzt auch das erste mal mit Threads wie man sicherlich gemerkt hat und war irgentwann doch sichtlich verwirrt was das ganze Thema angeht.
Jetzt setz ich mich erstmal ans Code aufräumen :)
 

Chris42

Mitglied
Hi Leute,
ich brauch wohl noch einmal eure Hilfe..

Ich versuche jetzt den Thread den ich gestartet habe zu pausieren/fortzusetzen und den Thread zu stoppen wenn man auf die entsprechenden Buttons drückt.

Leider scheint einfach gar nichts zu passieren, das "pause flag" wird allerdings gesetzt..

Hier nochmal die ActionListener Klasse:
Java:
package simulation.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JToggleButton;

import simulation.model.Territorium;

public class SimulationManager implements ActionListener {
	JToggleButton play;
	JToggleButton pause;
	JToggleButton stop;

	Territorium terri;
	Simulation simulation;

	public SimulationManager(JToggleButton play, JToggleButton pauseButton,
			JToggleButton stopButton, Territorium terri) {
		this.play = play;
		this.pause = pauseButton;
		this.stop = stopButton;
		this.terri = terri;
		this.simulation = new Simulation(this.terri);
	}

	@Override
	public void actionPerformed(ActionEvent e) {

		if (e.getSource() == this.play) {
			simulation.start();
		} else if (e.getSource() == this.stop) {
			simulation.stopSimulation();
		} else if (e.getSource() == this.pause) {
			if (this.pause.isSelected()) {
				System.out.println("Pause an");
				try {
					simulation.pauseSimulation();
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			} else {
				System.out.println("Pause aus");
				simulation.resumeSimulation();
			}
		}
	}
}

Und hier die Threadklasse:
Java:
package simulation.controller;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Observable;
import java.util.Observer;

import simulation.model.Actor;
import simulation.model.Territorium;
import exception.EndException;

public class Simulation extends Thread implements Runnable, Observer {

	Territorium terri;
	private volatile boolean paused = false;
	private Object lock = new Object();

	public Simulation(Territorium territorium) {
		super();
		this.terri = territorium;
	}

	@Override
	public synchronized void run() {
		checkIfPaused();

		Class<?> clas = this.terri.getActor().getClass();
		try {
			Method method = clas.getMethod("main", null);
			String[] params = null;
			try {
				method.invoke(this.terri.getActor(), params);
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void checkIfPaused() {
		synchronized (lock) {
			while (paused) {
				try {
					lock.wait();
					System.out.println("waiting..");
				} catch (InterruptedException exc) {

				}
			}
		}
	}

	public void stopSimulation() {
		Simulation.currentThread().stop();
	}

	public void pauseSimulation() throws InterruptedException {
		System.out.println("pause flag set");
		paused = true;
	}

	public synchronized void resumeSimulation() {
		synchronized (lock) {
			paused = false;
			lock.notify();
		}
	}

	@Override
	public void update(Observable o, Object arg) {
		if (Simulation.currentThread().getState() == Thread.State.TERMINATED) {
			try {
				throw new EndException();
			} catch (EndException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

Hat vielleicht jemand eine Idee woran das liegen kann? Habe mir jetzt schon diverse Beispiele angesehen und eingentlich tue ich genau das gleiche wie die anderen.
 
Zuletzt bearbeitet:

InfectedBytes

Top Contributor
ich vermute mal dass du die Methode checkIfPaused nicht aufrufst.
da diese Methode solange wartet, bis nicht mehr pausiert ist, musst du sie eben auch an den Stellen platzieren, welche pausieren sollen.
also z.b. innerhalb deiner vor() Methode.
 

Chris42

Mitglied
Gibt es eine Möglichkeit den Thread komplett zu killen? Habe das mit der stopSimulation() und der checkIfStopped() Methode versucht aber der bleibt bei mir immer an dem lock Object hängen glaube ich, dann passiert nämlich nichts bis ich das Programm in Eclipse kille.

Listener:
Java:
@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == this.play) {
			simulation.start();
			simulation = new Simulation(this.terri);
		} else if (e.getSource() == this.stop) {
			simulation.stopSimulation();
		} else if (e.getSource() == this.pause) {
			if (!paused) {
				paused = true;
				simulation.pauseSimulation();
			} else {
				paused = false;
				simulation.resumeSimulation();
			}
		}
	}

Thread:
Java:
package simulation.controller;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Observable;
import java.util.Observer;

import simulation.model.Territorium;
import exception.EndException;

public class Simulation extends Thread implements Runnable, Observer {

	Territorium terri;
	private volatile boolean paused = false;
	private volatile boolean stop = false;
	private Object lock = new Object();

	public Simulation(Territorium territorium) {
		super();
		this.terri = territorium;
	}

	@Override
	public synchronized void run() {
		Class<?> clas = this.terri.getActor().getClass();
		try {
			Method method = clas.getMethod("main", null);
			String[] params = null;
			try {
				method.invoke(this.terri.getActor(), params);
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println(this.getState());
	}

	public void checkIfPaused() {
		synchronized (lock) {
			while (paused) {
				try {
					lock.wait();
				} catch (InterruptedException exc) {
					Thread.currentThread().interrupt();
					return;
				}
			}
		}
	}

	public void checkIfStopped() {
		synchronized (lock) {
			while (stop) {
				synchronized (lock) {
					lock.notifyAll();
				}
			}
		}
	}

	public void stopSimulation() {
		stop = true;
	}

	public void pauseSimulation() {
		paused = true;
	}

	public void resumeSimulation() {
		paused = false;
		synchronized (lock) {
			lock.notifyAll();
		}
	}

	@Override
	public void update(Observable o, Object arg) {
		if (stop) {
			try {
				throw new EndException();
			} catch (EndException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

vor()- Methode:
Java:
public void move() {
		synchronized (this.territorium) {
			try {
				sim = (Simulation) Simulation.currentThread();
				sim.checkIfPaused();
				sim.checkIfStopped();
			} catch (ClassCastException c) {

			}
			boolean hadCorn = this.territorium.getHadCorn();

			try {
				switch (viewingDirection) {
				case (FACE_TO_NORTH):
					if (!this.territorium.nextIsWall(this.actY, this.actX)) {
						if (this.territorium.nextHasCorn(this.actY, this.actX)) {
							this.territorium.setHadCorn(true);
						} else {
							this.territorium.setHadCorn(false);
						}
						this.actY -= 1;
						territorium.tiles[this.actY][this.actX] = ACTOR_AT_TILE;
						if (hadCorn) {
							territorium.setCorn(actY + 1, actX);
						} else {
							territorium.clearPosition(actY + 1, actX);
						}
						try {
							Simulation.sleep(this.sleepTime);
						} catch (InterruptedException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
						break;
					} else {
						try {
							throw new DeadException();
						} catch (DeadException e) {

						}
					}
					break;

                         // ....other cases
 
Zuletzt bearbeitet:

InfectedBytes

Top Contributor
Das Problem ist, dass du einen Thread stoppen willst, dessen Programmcode eben noch nicht komplett abgearbeitet wurde. Ein Möglichkeit diesen "kontrolliert" zu stoppen wäre es Exceptions zu "missbrauchen".

Dazu erstellst du dir eine neue Exception Klasse, welche du beim stop wirfst.
Java:
public class StopException extends Exception { }

die run Methode deines Threads änderst du dann wie folgt ab, damit eine StopException dazu führt, dass der Thread verlassen wird.
Java:
public void run() {
  try {
    //dein "normaler" code, also die main ausführen oder ähnliches
  } catch(StopException e) {
    //gezielter Stopp
  }
}

Und natürlich musst du dann deine verschiedenen Methoden auch anpassen.
Java:
public void vor() throws StopException {
  //normaler code
  if(stop) throw new StopException();
}
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
P thread nimmt veränderte boolean nicht AWT, Swing, JavaFX & SWT 7
N JFrame loescht alles, sobald der Thread zuende ist AWT, Swing, JavaFX & SWT 22
M Server/Client thread von GUI Trennen AWT, Swing, JavaFX & SWT 2
K JavaFx, Sound Aufnahme und Thread AWT, Swing, JavaFX & SWT 0
T Exception in thread "main" java.lang.NoClassDefFoundError AWT, Swing, JavaFX & SWT 4
G Exception javafx Thread -> caused by removing children while in EventHandler AWT, Swing, JavaFX & SWT 28
H Event Handling Thread - Abruf der get-Methode AWT, Swing, JavaFX & SWT 5
J "Exception in thread "AWT-EventQueue-0"" Fehler AWT, Swing, JavaFX & SWT 3
G Thread starten Swing AWT, Swing, JavaFX & SWT 5
C Thread verwalten AWT, Swing, JavaFX & SWT 2
A Swing Exception in thread "AWT-EventQueue-0" AWT, Swing, JavaFX & SWT 1
S JavaFX Exception in thread "JavaFX Application Thread" AWT, Swing, JavaFX & SWT 3
L Label im JavaFX Thread Updaten AWT, Swing, JavaFX & SWT 3
ralfb1105 JavaFX Alert Confirmation Dialog aus einem Service Thread AWT, Swing, JavaFX & SWT 8
ralfb1105 JavaFX MVC: Thread in Model Class mit Ausgabe in TextArea AWT, Swing, JavaFX & SWT 10
D Swing SwingUtils / Thread Problem AWT, Swing, JavaFX & SWT 3
J Thread per Button starten AWT, Swing, JavaFX & SWT 10
J Thread kennt JButton nicht. AWT, Swing, JavaFX & SWT 11
T JavaFX Task / Thread / FXThread Komplikationen AWT, Swing, JavaFX & SWT 5
O Swing Event Dispatch Thread AWT, Swing, JavaFX & SWT 1
L JavaFX UI Thread block AWT, Swing, JavaFX & SWT 13
X Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1 AWT, Swing, JavaFX & SWT 6
sandaime Swing Thread für CMD auslesen AWT, Swing, JavaFX & SWT 16
E JavaFX JavaFX Application in Thread ausführen AWT, Swing, JavaFX & SWT 1
D JavaFX UI-Thread und DB-Thread trennen um z.B. Ladebalken anzuzeigen AWT, Swing, JavaFX & SWT 15
T JavaFX Controller im extra Thread AWT, Swing, JavaFX & SWT 0
T Swing 2 Thread.sleep parallel laufen lassen AWT, Swing, JavaFX & SWT 4
L Zweites Fenster mit Thread AWT, Swing, JavaFX & SWT 0
E JavaFX Stage.show() in ursprünglichem Thread starten AWT, Swing, JavaFX & SWT 7
L Swing Frame in Thread wird nicht gezeichnet AWT, Swing, JavaFX & SWT 2
N Programm mit Swing und Thread, Figur bewegen sich nicht AWT, Swing, JavaFX & SWT 6
C Im ActionListener Buttons disablen, einen Thread starten, dann Buttons enablen AWT, Swing, JavaFX & SWT 2
T Swing Button bleibt grau [=> UI hat sich aufgehängt, Aufgabe in Thread auslagern] AWT, Swing, JavaFX & SWT 3
M Thread-Frage in SWT AWT, Swing, JavaFX & SWT 1
Q GUI außerhalb GUI-Thread updaten - GUI friert ein AWT, Swing, JavaFX & SWT 18
C Thread in Klassen starten AWT, Swing, JavaFX & SWT 4
L exception in thread awt-eventqueue-0 java.lang.nullpointerexception AWT, Swing, JavaFX & SWT 2
S Swing Exception in thread "AWT-EventQueue-0" bei Jlabel AWT, Swing, JavaFX & SWT 4
D SWT SWT Elemente aus anderen Klassen aufrufen - Invalid thread access AWT, Swing, JavaFX & SWT 6
K JavaFX Tableview mit fxml ohne Aktualiserung trotz Thread AWT, Swing, JavaFX & SWT 13
K Event Handling 2 Buttons und Thread stop AWT, Swing, JavaFX & SWT 3
C Swing Update von swing-TableModels per Thread. Eins geht, das andere nicht, warum? AWT, Swing, JavaFX & SWT 12
V JLabel bzw. GUI aus externen Thread ansteuern AWT, Swing, JavaFX & SWT 3
J Applet Paralleles Thread Handling AWT, Swing, JavaFX & SWT 3
H Swing JfreeChart aktualisieren - mit daten aus thread AWT, Swing, JavaFX & SWT 3
T Java Swing Main GUI Thread AWT, Swing, JavaFX & SWT 3
C Event Handling Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException AWT, Swing, JavaFX & SWT 43
T Table-Zeilen mit Thread einfärben AWT, Swing, JavaFX & SWT 15
F Swing GUI-Thread für automatisches Update nutzen AWT, Swing, JavaFX & SWT 10
Y KeyListener, GUI Thread, repaint AWT, Swing, JavaFX & SWT 7
V Nullpointerexception (etwas mit thread und jframe) AWT, Swing, JavaFX & SWT 3
P Problem Thread.sleep() und JProgressBar AWT, Swing, JavaFX & SWT 7
S SWT GUI-Thread AWT, Swing, JavaFX & SWT 11
A Thread und sleep(1000); AWT, Swing, JavaFX & SWT 7
B Swing Thread+Animation AWT, Swing, JavaFX & SWT 7
S Timer oder Thread.sleep AWT, Swing, JavaFX & SWT 3
M Exception in thread "Thread-3" java.lang.NullPointerException AWT, Swing, JavaFX & SWT 18
B Über SWT Button Thread beenden AWT, Swing, JavaFX & SWT 2
C SWT Gui Thread hängt sich auf AWT, Swing, JavaFX & SWT 3
lumo SWT Exception in thread "main" org.eclipse.swt.SWTError: No more handles AWT, Swing, JavaFX & SWT 3
Luk10 Swing Problem mit Zeichen-Thread AWT, Swing, JavaFX & SWT 8
G 2D-Grafik Von Thread aus Zeichnen AWT, Swing, JavaFX & SWT 5
U Swing JLabel bewegen mittels Thread AWT, Swing, JavaFX & SWT 3
M JProgressBar für einen Thread AWT, Swing, JavaFX & SWT 14
R JTable und Thread AWT, Swing, JavaFX & SWT 4
K Thread.sleep in GUI AWT, Swing, JavaFX & SWT 4
J Thread funktioniert nicht AWT, Swing, JavaFX & SWT 10
D JPanel mit Thread in JPanel AWT, Swing, JavaFX & SWT 4
F Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: null AWT, Swing, JavaFX & SWT 5
P Teil einer Swing GUI in eigenem Thread AWT, Swing, JavaFX & SWT 4
S Thread.sleep() in einer methode fürs zeichen AWT, Swing, JavaFX & SWT 3
O JTree/TreeModel/DefaultMutableTreeNodes thread safe machen AWT, Swing, JavaFX & SWT 3
P repaint während Thread läuft AWT, Swing, JavaFX & SWT 9
F SWT table refresh per Thread AWT, Swing, JavaFX & SWT 2
V Swing remove(Component) blockiert Thread sehr lange. AWT, Swing, JavaFX & SWT 6
J AWT Artefakte bei AWT-Rendering durch parallelen Thread AWT, Swing, JavaFX & SWT 4
H Thread-Problem mit der Darstellung beim Sperren des Fensters AWT, Swing, JavaFX & SWT 2
T Event Dispatch Thread und noch ein Thread AWT, Swing, JavaFX & SWT 7
Burny91 Swing Thread mit wait() und notify() steuern AWT, Swing, JavaFX & SWT 22
N SWT - über Thread Composite erstellen und Anhängen AWT, Swing, JavaFX & SWT 6
K Vom Gui aus auf einen Thread warten AWT, Swing, JavaFX & SWT 4
X Problem bei JTextArea und Thread.sleep() AWT, Swing, JavaFX & SWT 8
F Merkwürdiges Verhalten zeichnen sperater Thread AWT, Swing, JavaFX & SWT 13
B Swing Swing und Thread.sleep() AWT, Swing, JavaFX & SWT 6
N Exception Behandlung mit setDefaultUncaughtExceptionHandler, insbesondere im EventDispatcher Thread AWT, Swing, JavaFX & SWT 4
Q Neuer Thread zum Öffnen AWT, Swing, JavaFX & SWT 2
P Swing GUI im Thread? AWT, Swing, JavaFX & SWT 5
T GUI JFrame - neuer Thread AWT, Swing, JavaFX & SWT 2
data89 Was mache ich mit "Dispatched Event Thread"/Substance falsch? AWT, Swing, JavaFX & SWT 4
0x7F800000 Allg. Frage zum ev. dispatch thread, wie korrekt auf reaktion der Listener warten? AWT, Swing, JavaFX & SWT 4
S Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException AWT, Swing, JavaFX & SWT 7
T thread.sleep Sprung Problem AWT, Swing, JavaFX & SWT 24
N Server mit Thread und Statusbox AWT, Swing, JavaFX & SWT 3
S Objektverhalten in einen Thread legen AWT, Swing, JavaFX & SWT 4
G JProgressBar actionPerformedMethode und SwingUI thread AWT, Swing, JavaFX & SWT 36
E Komponenten in Event Dispatch Thread erzeugen? AWT, Swing, JavaFX & SWT 4
J Thread in GUI einbauen AWT, Swing, JavaFX & SWT 2
Lony AbstractTableModel Exception in thread "AWT-EventQueue- AWT, Swing, JavaFX & SWT 3
A Ticker als Thread AWT, Swing, JavaFX & SWT 3
G Auf Ergebnis vom Thread warten AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben