Kleines Problem mit Threads (synchronized)

Status
Nicht offen für weitere Antworten.

MFM

Mitglied
Hi Leute,

ich habe hier zur Klausurvorbereitung ne Kleine Parkhaussimulation geschrieben.
Ich habe 1 Parkhaus mit 10 freien Plätzen und 40 Autos (wird alles in der main instanziiert)

Sobald ich aber bei 0 freien Plätzen ankomme, geht nix mehr. Ich nehme an, dass das daran liegt, dass ich, wenn ich im synchronized Block der einlass-Methode bin, der Scheduler keine anderen Threads mehr dranbringt.

Leider lässt sich das Problem aber auch nicht durch eine sleep-Anweisung dort lösen.

Für jeden Input wäre ich sehr sehr dankbar!

Java:
public class ParkhausSim {

	public static void main(String[] args){
		
		Parkhaus p1 = new Parkhaus(10);
		
		for(int i=1 ; i <=40; i++){
			Auto a = new Auto(p1);
			a.start();
			i++;
		}
	}
}

Java:
public class Auto extends Thread{
	
	public Parkhaus monitor;
	
	public Auto(Parkhaus monitor){
		this.monitor = monitor;
	}
	
	public void run(){
		
		// Auto ist auf der Strasse und 
		// "fährt" (schläft) eine random-Zeit (bis zu 10 Sekunden)
		// bis zum Parkhaus
		
		try {
			Thread.sleep((long)(10*Math.random()));
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		// Dann versucht es, in das Parkhaus einzufahren
		synchronized(monitor){
			monitor.einlass();
		}
		
		// Im Parkhaus steht das Auto, bis der Besitzer nach einer
		// random-Zeit das Auto wieder abholt
		try {
			Thread.sleep((long)(10*Math.random()));
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		// Und dann geht es wieder ab nach Hause
		synchronized(monitor){
			monitor.auslass();
		}
	}
}

Java:
public class Parkhaus {

	public int freie_plaetze;
	
	public Parkhaus(int plaetze){
		this.freie_plaetze = plaetze;
	}
	
	synchronized void einlass(){
		while(freie_plaetze == 0){
			// Solange das Parkhaus besetzt ist
			// warte hier an der Einlassschranke
			
			// und schau mal, ob nicht jemand mal rausfahren möchte
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		// Sobald wieder ein Platz frei wurde
		// oder eh schon mind. ein Platz frei war
		freie_plaetze--;
		System.out.println("Auto eingefahren: Es gibt noch " +freie_plaetze+ " freie Plaetze");
	}
	
	synchronized void auslass(){
		freie_plaetze++;
		System.out.println("Auto eingefahren: Es gibt wieder " +freie_plaetze+ " freie Plaetze");
	}	
}

LG MFM
 
>Sobald ich aber bei 0 freien Plätzen ankomme, geht nix mehr. Ich nehme an, dass das daran liegt, dass ich, wenn ich im synchronized Block der einlass-Methode bin, der Scheduler keine anderen Threads mehr dranbringt.

so auf die schnelle ja. Sobald du in der Endlosschleife bist, ist das Parkhaus gelockt.

Den synchronized(monitor) ist überflüssig. die Methode ist schon synchronized.

Der Aufbau ist irgendwie falsch. Ein Auto besitzt ein Parkhaus? Neeee. Ein Parkhaus besitzt x Autos.
 
Naja, "falsch" würd' ich nicht sagen. Die Autos sind die Threads, das passt, und die müssen was mit dem Parkhaus machen - nämlich reinfahren - und dazu müssen sie es zumindest kennen

Zum eigentlichen Problem: Das hängt vermutlich wirklich mit dem "while" in de synchronisierten einlass-Methode zusammen. Bildlich gesprochen: Es gibt keine Schranke, die den Einlass verweigert, sondern nur einen Pförtner, der die Autos am reinfahren hindert, und deswegen nicht mitkriegt, wenn ein anderes Auto rausfährt. Etwas weniger bildlich: Schau dir mal "wait" und "notify/notifyAll" an - ggf. mit sowas wie Guarded Blocks (The Java™ Tutorials > Essential Classes > Concurrency).
 
ja, so wie marco13 das geschrieben hat, hab ich das auch gemeint.

Das mit dem Monitor habe ich gemacht, weil die ja alle ins selbe Parkhaus fahren sollen.

Und in der Tat ist es so, dass ich durch die while-Schleife in einen Totzustand gerate (Deadlock).
Die Aufgabe habe ich dann auch mittels wait/notify gelöst.

Vielen Dank
MFM
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben