Threads Synchronisationsproblem

eLwoodianer

Mitglied
Hallo zusammen!

Folgende Aufgabenstellung: Es gibt einen Sprungwettwettbewerb mit 5 Personen. Der Sprungturm ist 30 Sekunden geöffnet. Ein Sprung dauert zwischen zwischen 1 und 5 Sekunden. Der selbe Springer kann theoretisch mehrmals hintereinander springen.

Meine Umsetzung soweit:
  • Ein Sprungturmobjekt
  • Fünf Springer-Threads die versuchen zu springen
  • Ein Bademeister-Thread der den Sprungturm nach 30 Sekunden zumacht.

Problem: Die Springer springen länger als 30 Sekunden. Ich versteh warum das so ist, nur komm ich nicht auf die Lösung. :(

Java:
public class JumpingCompetition {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		DivingPlatform dp = new DivingPlatform();
		
		Diver bart = new Diver(dp, "Bart");
		Thread diver1 = new Thread(bart);
		
		Diver lisa = new Diver(dp, "Lisa");
		Thread diver2 = new Thread(lisa);
		
		Diver homer = new Diver(dp, "Homer");
		Thread diver3 = new Thread(homer);
		
		Diver marge = new Diver(dp, "Marge");
		Thread diver4 = new Thread(marge);
		
		Diver maggie = new Diver(dp, "maggie");
		Thread diver5 = new Thread(maggie);
		
		PoolAttendant moe = new PoolAttendant(dp);
		Thread poolAttendant = new Thread(moe);

		poolAttendant.start();
		diver1.start();
		diver2.start();
		diver3.start();
		diver4.start();
		diver5.start();
	}

}

Java:
public class Diver implements Runnable {

	private DivingPlatform dp;
	private String name;
	
	public Diver(DivingPlatform dp, String name) {
		this.dp= dp;
		this.name = name;
	}
	
	@Override
	public void run() {
		while(dp.isOpen()) {
				this.dp.jump((int) (Math.random()*5)+1, this.name);
		}		
	}

}

Java:
public class DivingPlatform {
	
	boolean open;
	
	public DivingPlatform() {
		this.open = true;
	}
	
	public boolean isOpen() {
		return this.open;
	}
	
	public void close() {
		this.open = false;
	}
	
	public synchronized void jump(int jumpTime, String name) {
		try {
			System.out.println(name + " springt! Sprungzeit: " + jumpTime);
			Thread.sleep(jumpTime*1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

Java:
public class PoolAttendant implements Runnable {

	DivingPlatform divingPlatformToClose;
	
	public PoolAttendant(DivingPlatform divingPlatformToClose) {
		this.divingPlatformToClose = divingPlatformToClose;
	}
	
	@Override
	public void run() {
		try {
			Thread.sleep(30000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.divingPlatformToClose.close();	
	}

}

Vielen Dank
eL
 

Fu3L

Top Contributor
Wenn du vor isOpen() und close() ein synchronized setzt, müsste es eigentlich gehen, wenn ich beim Überfliegen nichts übersehen habe^^
 
S

SlaterB

Gast
ein Problem ist im Moment: wenn alle Threads ihr isOpen() geprüft haben und in die Schleife eintreten, dann warten sie dort wegen der Synchronisation und gehen nicht etwa zur Schleifenbedingung zurück/ vorwärts,
im Falle des close()-Aufrufs könnte also gerade ein Thread jumpen und alle anderen warten, diese kommen dann auch alle noch dran, weil nicht mehr geprüft wird ob geschlossen,
dagegen kann z.B. helfen, in der jump-Methode nochmal isOpen() abzufragen

in jedem Fall kann mit dem bisherigen Konzept mindestens ein Thread über die 30 sec hinausspringen, egal wie geprüft wird oder ob close() per Synchronisierung geordnet eingreift,
im letzteren Fall kann es per Zufall nach den 30 sec ziemlich lange dauern, bis close() und nicht andere jump()-Aufrufe Zugriff auf die Klasse bekommen, vielleicht keine gute Idee
 

eLwoodianer

Mitglied
... kann z.B. helfen, in der jump-Methode nochmal isOpen() abzufragen

in jedem Fall kann mit dem bisherigen Konzept mindestens ein Thread über die 30 sec hinausspringen, ...

Danke! Das einer der Threads über die 30 Sekunden hinausspringen kann ist okay. Dein Lösungsvorschlag funktioniert soweit. Wobei mir das noch nicht 100%ig gefällt. Liegt aber in dem Fall eher an meinem Lösungsansatz für die Aufgabenstellung glaub ich.

Edit: Hab eine elegante Lösung gefunden. :)

eL
 
Zuletzt bearbeitet:

Ähnliche Java Themen

Neue Themen


Oben