Nebenläufigkeit, Threads und Synchronisation

Status
Nicht offen für weitere Antworten.

BlubBlub

Bekanntes Mitglied
Folgende Aufgabenstellung:

In dieser Aufgabe soll die Zugangskontrolle für eine Sauna simuliert werden. Es gelten folgende Bedingungen:
• Die Sauna ist sehr groß. Sie kann beliebig viele Leute gleichzeitig aufnehmen.
• Die Sauna soll nur getrennt geschlechtlich genutzt werden, d.h., es dürfen sich nicht gleichzeitig Männer und
Frauen in der Sauna aufhalten.
• Es gibt keine festen Frauen- oder Männerzeiten. Die erste Person welche die Sauna betritt „sperrt“ sie für das
andere Geschlecht, bis die Sauna wieder komplett unbesetzt ist.
• Wenn bereits eine Person eines Geschlechts in der Sauna ist, dürfen weitere Personen desselben Geschlechts
dazu kommen.

Schreiben Sie ein Programm, das in zufälligen Zeitabständen Personen-Objekte eines zufälligen Geschlechts erzeugt,
die eine zufällig lange Zeit die Sauna benutzen wollen, und das die Wartesituation vor der Sauna und Verweilsituation
in der Sauna durch geeignete Ausgaben simuliert.

Bemerkung: Bei ungünstiger Wahl der der zufälligen Parameter kann es sein, dass es nie zu einen Wechsel zwischen
Frauen und Männern kommt. Variieren Sie die Parameter. Wie man eine solche Situation allgemein verhindern kann
lernen Sie in Kapitel 7 der Vorlesung


Meine Lösung:

Java:
public class SaunaMonitor
{
	private int personenanzahl;
	private String geschlecht;
	
	public synchronized void goIn(Person gast)
	{
		System.out.println("Eintritt von Gast Nr.: " + gast.getBesuchernummer() + " Geschlecht: " + gast.getGeschlecht() + " Wartezeit " 
				           + gast.getWartezeit() + " Verweilzeit " + gast.getVerweilzeit());
		
		if(personenanzahl == 0)
		{
			this.geschlecht = gast.getGeschlecht();
		}
		
		while( !(this.geschlecht.equals(gast.getGeschlecht())) )
		{
			if(gast.getWartezeit() >= 0)
				gast.decrWartezeit();
			else System.out.println("Gast Nr. " + gast.getBesuchernummer() + "wollte nicht mehr warten  Geschlecht: " + gast.getGeschlecht() + " Wartezeit " 
			           + gast.getWartezeit() + " Verweilzeit " + gast.getVerweilzeit());
			
			try
			{
				wait();
			}
			catch(InterruptedException e){}
		}
		
		if(gast.getWartezeit() >= 0)
			personenanzahl++;
	}
	
	public synchronized void goOut(Person gast)
	{
		System.out.println("Verlassen von Gast Nr.: " + gast.getBesuchernummer() + " Geschlecht: " + gast.getGeschlecht() + " Wartezeit " 
		           + gast.getWartezeit() + " Verweilzeit " + gast.getVerweilzeit());
		
		personenanzahl--;
		
		notifyAll();
	}
}



public class Person extends Thread
{
	private SaunaMonitor sauna;
	private String geschlecht;
	private int verweilzeit;
	private int wartezeit;
	private int besuchernummer;
	
	public Person(SaunaMonitor sauna, int besuchernummer)
	{
		if((int)(Math.random()*10+1) > 5)
			this.geschlecht = "w";	
		else
			this.geschlecht = "m";
	
		this.verweilzeit = (int)(Math.random()*1000+1);
		this.wartezeit = (int)(Math.random()*3000+1);
		this.sauna = sauna;
		this.besuchernummer = besuchernummer;	
	}
	
	public void run()
	{
		sauna.goIn(this);
		
		try
		{
			sleep(verweilzeit);
		}
		catch(InterruptedException e){}
		
		sauna.goOut(this);
	}
	
	public String getGeschlecht(){return geschlecht;}
	public int getVerweilzeit(){return verweilzeit;}
	public int getWartezeit(){return wartezeit;}
	public int getBesuchernummer(){return besuchernummer;}
	public void decrWartezeit(){wartezeit = wartezeit - 500;}

}





public class Zugangskontrolle 
{

	public static void main(String[] args)
	{
		SaunaMonitor sauna = new SaunaMonitor();
		int besucheranzahl = (int)(Math.random()*20+1);
		
		System.out.println("Kontrollausgabe(Besucheranzahl): " + besucheranzahl);
		
		for(int i = 1; i <= besucheranzahl; i++)
		{
			new Person(sauna, i).start();
		}
	}
}


Meine Frage:

Wenn ich mein Programm laufen lasse, dann kommts gerade zu dem Dead-Lock, also es kommt zu keinem Wechsel zwischen den Männern und Frauen.
Woran liegt das?
Würd ich das Dead-Lock Problem ignorieren wäre die Aufgabe denn so richtig gelöst, wenn ich Dead-Locks zulasse, oder ist da irgendwo ein Fehler, weil ich nicht weiß woran ich erkenne ob ich richtig programmiert habe oder nicht, da ich nicht weiß worauf man beim Testen von Threads und Synchronisationen achten muss um Aussagen zu können ob man richtig an die Aufgabe ran gegangen ist.
Ich hoff ihr könnt mir helfen und etwas zu meinem Programm sagen.
 
S

SlaterB

Gast
ich habe keinen Dead-Lock festgestellt, aber das Programm ist ja auch massiv zufallsgesteuert,
gibt doch mal eine feste Liste von Personen und Wartezeiten usw. vor, damit alle einigermaßen über das gleiche reden,

was mir bisher aufgefallen ist:
das Log gibt gar nicht wieder ob und wann ein Wechsel stattfindet, man kann nicht mal erkennen, ob eine Person auch wirklich in die Saue reinkommt,
"Eintritt von Gast" erscheint für jeden, "Verlassen von Gast" ebenso, manche sagen zwischendurch "wollte nicht mehr warten",
aber das ist sehr schlecht zu verfolgen,
nett wäre am Ende noch eine separate Auswertung pro Gast:
Nr, kam um .., kam in die Saune, ging, warte .. Zeit, maximal ..,
usw.

außerdem scheint mir das Warten nicht korrekt umgesetz,
du hast nur wait(), und wenn einer rausgeht gibts notifyAll() und alle wartenden ziehen 500ms von ihrer Wartezeit ab,
wieso 500ms und nicht 50 oder 5000?
ich denke hier musst du exakt arbeiten, die genaue Systemzeit zu Beginn des Wartens vermerken und mit der aktuellen Zeit vergleichen,

außerdem die Warte-Schleife abbrechen, wenn die Zeit rum ist, nicht erst auf den Wechsel des Geschlechts warten,
da ist vielleicht der Dead-Lock: wenn alle Männer raus sind, und die Frauen warten, wer kümmert sich um den Wechsel?
in die Warteschleife vielleicht auch die Anzahl der Personen einbauen

und dann noch ein falscher Ansatz:
alle Personen kommen bei dir am Anfang des Programms,
du musst simulieren, dass sie zu einer zufälligen Zeit kommen,
 

BlubBlub

Bekanntes Mitglied
ich hab meine quelltext ein wenig kommentiert zum besseren verständnis:

Java:
public class SaunaMonitor
{
	private int personenanzahl;
	private String geschlecht;
	
	public synchronized void goIn(Person gast) //eintritt in die sauna
	{
		if(personenanzahl == 0) // wenn noch keine person in der sauna drin ist, bestimmt die person die grad reingeht ob die sauna für männer oder frauen grad offen ist
		{
			this.geschlecht = gast.getGeschlecht();
		}
		
		while( !(this.geschlecht.equals(gast.getGeschlecht())) ) // falls schon mehrere personen in der sauna drin sind, wird hier geschaut ob der gast der dem zugelassenen geschlecht entspricht
		{
			if(gast.getWartezeit() >= 0) // wenn der gast dem zugelassenen geschlecht nicht entspricht, wird seine geduld verringert
				gast.decrWartezeit();
			else System.out.println("Gast Nr. " + gast.getBesuchernummer() + "wollte nicht mehr warten  Geschlecht: " + gast.getGeschlecht() + " Wartezeit " 
			           + gast.getWartezeit() + " Verweilzeit " + gast.getVerweilzeit());  // ist die geduld des gastes erschöpft so verlässt er das schwimmbad
			
			try
			{
				wait(); // stimmt das geschlecht des gastes mit dem zugelassenen geschlecht nicht ein, so wird er blockiert und wartet auf ein notifyAll() bevor er abermals versucht reinzukommen, wenn er schnell genug war
			}
			catch(InterruptedException e){}
		}
		
		if(gast.getWartezeit() >= 0) // stimmt das geschlecht des gastes mit dem zugelassenen geschlecht überein erreicht er diese if-anweisung und es wird überprüft ob seine geduld zu warten nicht schon erschöpft ist
		{
			System.out.println("Eintritt in die Sauna von Gast Nr.: " + gast.getBesuchernummer() + " Geschlecht: " + gast.getGeschlecht() + " Wartezeit " 
			           + gast.getWartezeit() + " Verweilzeit " + gast.getVerweilzeit()); // information über den gast der grad die sauna betritt
			
			personenanzahl++; //wenn alles stimmt geht er in die sauna rein
		}
	}
	
	public synchronized void goOut(Person gast) //verlassen der sauna
	{
		System.out.println("Verlassen der Sauna von Gast Nr.: " + gast.getBesuchernummer() + " Geschlecht: " + gast.getGeschlecht() + " Wartezeit " 
		           + gast.getWartezeit() + " Verweilzeit " + gast.getVerweilzeit()); //informationen über den gast der die sauna verlassen hat
		
		personenanzahl--; //da die person nicht mehr in der sauna ist wird die personanzahl um eins minimiert
		
		notifyAll(); // alle blockierten prozesse werden geweckt, und die blockierten gäste versuchen in die sauna reinzustürmen
	}
}

Java:
public class Person extends Thread
{
	private SaunaMonitor sauna;
	private String geschlecht;
	private int verweilzeit; // gibt an wie lange der besucher in der sauna bleibt
	private int wartezeit; // gibt an wie lange der besucher bereit ist vor der sauna zu warten, um reinzukommen
	private int besuchernummer;
	
	public Person(SaunaMonitor sauna, int besuchernummer)
	{
		if((int)(Math.random()*10+1) > 5) // zufällige bestimmund des geschlechts des besuchers
			this.geschlecht = "w";	
		else
			this.geschlecht = "m";
	
		this.verweilzeit = (int)(Math.random()*10000+1); // zufällige bestimmung der verweilzeit 
		this.wartezeit = 3000; //zum besseren vergleich haben alle gäste dieselbe geduld
		this.sauna = sauna;
		this.besuchernummer = besuchernummer;	
	}
	
	public void run()
	{
		sauna.goIn(this); // gast versucht in die sauna reinzugehen, sobald der monitor freigegeben ist
		
		try
		{
			sleep(verweilzeit); // simmuliert die verweilzeit des gastes in der sauna, wenn er drin ist
		}
		catch(InterruptedException e){}
		
		sauna.goOut(this); // anschließend verlässt der besucher die sauna, und ruft notifyAll(), denn wenn dies der letzte weibliche gast in der sauna war, können durch notifyAll() nun auch versuchen die männer reinzukommen
	}
	
	public String getGeschlecht(){return geschlecht;}
	public int getVerweilzeit(){return verweilzeit;}
	public int getWartezeit(){return wartezeit;}
	public int getBesuchernummer(){return besuchernummer;}
	public void decrWartezeit(){wartezeit = wartezeit - 500;}

}

Java:
public class Zugangskontrolle 
{

	public static void main(String[] args)
	{
		SaunaMonitor sauna = new SaunaMonitor();
		int besucheranzahl = 10; // zum bessere vergleich erstmal 10 besucher erzeugen 
		
		System.out.println("Kontrollausgabe(Besucheranzahl): " + besucheranzahl);
		
		for(int i = 1; i <= besucheranzahl; i++)
		{
			new Person(sauna, i).start();
		}
	}
}


und hier mal ein beispiel ergenbis welches geliefert wurde:

Kontrollausgabe(Besucheranzahl): 10
Eintritt in die Sauna von Gast Nr.: 1 Geschlecht: w Wartezeit 3000 Verweilzeit 5707
Eintritt in die Sauna von Gast Nr.: 3 Geschlecht: w Wartezeit 3000 Verweilzeit 9759
Eintritt in die Sauna von Gast Nr.: 2 Geschlecht: w Wartezeit 3000 Verweilzeit 3807
Eintritt in die Sauna von Gast Nr.: 6 Geschlecht: w Wartezeit 3000 Verweilzeit 7429
Eintritt in die Sauna von Gast Nr.: 9 Geschlecht: w Wartezeit 3000 Verweilzeit 3567
Eintritt in die Sauna von Gast Nr.: 8 Geschlecht: w Wartezeit 3000 Verweilzeit 9682
Verlassen der Sauna von Gast Nr.: 9 Geschlecht: w Wartezeit 3000 Verweilzeit 3567
Verlassen der Sauna von Gast Nr.: 2 Geschlecht: w Wartezeit 3000 Verweilzeit 3807
Verlassen der Sauna von Gast Nr.: 1 Geschlecht: w Wartezeit 3000 Verweilzeit 5707
Verlassen der Sauna von Gast Nr.: 6 Geschlecht: w Wartezeit 3000 Verweilzeit 7429
Verlassen der Sauna von Gast Nr.: 8 Geschlecht: w Wartezeit 3000 Verweilzeit 9682
Verlassen der Sauna von Gast Nr.: 3 Geschlecht: w Wartezeit 3000 Verweilzeit 9759




Anmerkung: das programm läuft immer noch weiter nach dieser ausgabe erzeugt aber
keine neuen ausgaben

---------------------------------------------------------------------------------


gibt doch mal eine feste Liste von Personen und Wartezeiten usw. vor, damit alle einigermaßen über das gleiche reden
Gesamtanzahl der Besucher: 10
Wartezeiten, also die Geduld die jeder Besucher hat bevor er keine lust mehr hat
auf den Saunaeintritt zu warten: 3 sekunden (wobei das sind nicht echte zeitsekunden, sondern die zeit wird immer runtergezählt um 0,5 sekunden falls ein gast
in die synchronisierte methode goIn(Person gast) reinkommt, aber wegen seines geschlechts die sauna nicht betretten kann und deshalb wieder blockiert wird und die
methode für andere wieder freigibt.



das Log gibt gar nicht wieder ob und wann ein Wechsel stattfindet, man kann nicht mal erkennen, ob eine Person auch wirklich in die Saue reinkommt,
"Eintritt von Gast" erscheint für jeden, "Verlassen von Gast" ebenso, manche sagen zwischendurch "wollte nicht mehr warten",
aber das ist sehr schlecht zu verfolgen,
nett wäre am Ende noch eine separate Auswertung pro Gast:
Nr, kam um .., kam in die Saune, ging, warte .. Zeit, maximal ..,
usw.
ob ein gast in die sauna reinkommt, gibt der text wieder der durch das System.out.println("....") in der goIn(Person gast) Methode ausgegeben wird
(hab den System.out.println befehl jetzt in die letzt if anweisung gelegt, im vergleich zu meinem ersten beitrag)


außerdem scheint mir das Warten nicht korrekt umgesetz,
du hast nur wait(), und wenn einer rausgeht gibts notifyAll() und alle wartenden ziehen 500ms von ihrer Wartezeit ab,
wieso 500ms und nicht 50 oder 5000?
ich denke hier musst du exakt arbeiten, die genaue Systemzeit zu Beginn des Wartens vermerken und mit der aktuellen Zeit vergleichen,
naja was das warten angeht hab ich grad weiter oben erklärt dass das nicht "echte sekunden" sind, da ich nicht weiß wie man das macht.
und es werden immer 0,5 sekunden abgezogen, weil mir das grad so spontan
eingefallen ist, das ist nur irgendein wert der die zu reduzierende geduld des gastes
darstellen soll, falls er den monitor für sich bekommen hat aber auf grund des
geschlechts nicht reingekommen ist


und dann noch ein falscher Ansatz:
alle Personen kommen bei dir am Anfang des Programms,
du musst simulieren, dass sie zu einer zufälligen Zeit kommen,
in schwimmbad kommen jetzt 10 leute durch die for schleife in der " zugangskontrolle "
gleichzeitig rein, aber in die sauna kommen sie nicht gleichzeitig rein sondern zu zufälligen zeitpunken.
so hatte ich das verstanden, aber mag sein dass ich das falsch verstanden hab.
dann müsst ich in der zugangskontrolle in der for schleife ein sleep( zufallszeit ) noch reinsetzen
 
S

SlaterB

Gast
der Deadlock ist immer noch: wenn erstmal die erste Gruppe aus der Sauna raus ist, ob Männer oder Frauen,
warten die anderen immer noch in der Schleife

> while( !(this.geschlecht.equals(gast.getGeschlecht())) )

denn niemand stellt z.B. die Variable um
 

BlubBlub

Bekanntes Mitglied
Java:
if(personenanzahl == 0) 
{
          this.geschlecht = gast.getGeschlecht();
}

wenn alle frauen zum beispiel draussen sind, dann ist personenanzahl = 0;
und das zugelassen geschlecht ist "w".
das macht aber nichts da sobald ein mann reingeht, wird erstmal auf die personenanzahl geguckt und nicht auf das geschlecht.
ist sie wie in dem genannten fall 0 so stellt der mann das zugelassene geschlecht auf "m".
somit erfolt ein umstellung des geschlechts.

ah sorry jetzt seh ich den fehler darin.
sobald die gäste einmal blockiert wurden und dann durch notifyAll() geweckt werden dann durchlaufen sie ja nicht mehr die überprüfung in der if anweisung
 
Zuletzt bearbeitet:

BlubBlub

Bekanntes Mitglied
so hab den fehler jetzt korrigiert:

Java:
public class SaunaMonitor
{
	private int personenanzahl;
	private String geschlecht;
	
	public synchronized void goIn(Person gast) //eintritt in die sauna
	{
		if(personenanzahl == 0) // wenn noch keine person in der sauna drin ist, bestimmt die person die grad reingeht ob die sauna für männer oder frauen grad offen ist
		{
			this.geschlecht = gast.getGeschlecht();
		}
		
		while( !(this.geschlecht.equals(gast.getGeschlecht())) && !(this.geschlecht.equals(""))  ) // falls schon mehrere personen in der sauna drin sind, wird hier geschaut ob der gast der dem zugelassenen geschlecht entspricht oder falls keine person drin ist dann darf der gast in die sauna und muss nicht mehr warten
		{
			if(gast.getWartezeit() >= 0) // wenn der gast dem zugelassenen geschlecht nicht entspricht, wird seine geduld verringert
				gast.decrWartezeit();
			else System.out.println("Gast Nr. " + gast.getBesuchernummer() + "wollte nicht mehr warten  Geschlecht: " + gast.getGeschlecht() + " Wartezeit " 
			           + gast.getWartezeit() + " Verweilzeit " + gast.getVerweilzeit());  // ist die geduld des gastes erschöpft so verlässt er das schwimmbad
			
			try
			{
				wait(); // stimmt das geschlecht des gastes mit dem zugelassenen geschlecht nicht ein, so wird er blockiert und wartet auf ein notifyAll() bevor er abermals versucht reinzukommen, wenn er schnell genug war
			}
			catch(InterruptedException e){}
		}
		
		if(gast.getWartezeit() >= 0) // stimmt das geschlecht des gastes mit dem zugelassenen geschlecht überein erreicht er diese if-anweisung und es wird überprüft ob seine geduld zu warten nicht schon erschöpft ist
		{
			System.out.println("Eintritt in die Sauna von Gast Nr.: " + gast.getBesuchernummer() + " Geschlecht: " + gast.getGeschlecht() + " Wartezeit " 
			           + gast.getWartezeit() + " Verweilzeit " + gast.getVerweilzeit()); // information über den gast der grad die sauna betritt
			
			personenanzahl++; //wenn alles stimmt geht er in die sauna rein
		}
	}
	
	public synchronized void goOut(Person gast) //verlassen der sauna
	{
		System.out.println("Verlassen der Sauna von Gast Nr.: " + gast.getBesuchernummer() + " Geschlecht: " + gast.getGeschlecht() + " Wartezeit " 
		           + gast.getWartezeit() + " Verweilzeit " + gast.getVerweilzeit()); //informationen über den gast der die sauna verlassen hat
		
		personenanzahl--; //da die person nicht mehr in der sauna ist wird die personanzahl um eins minimiert
		
		if(personenanzahl == 0)
			this.geschlecht = "";
		
		gast.resetWartezeit(); // sobald der gast draussen ist kann er erneut versuchen in die sauna reinzugehen, seine geduld wird wieder neugesetzt => wartezeit
		
		notifyAll(); // alle blockierten prozesse werden geweckt, und die blockierten gäste versuchen in die sauna reinzustürmen
	}
}

die korrektur mit dem umstellen des geschlechts ist erfolgt in den zeilen 13, 43/44 ...
in zeile 46 hab ich eine anweisung dazugeschrieben damit der besucher der grad raus ist, erneut in die sauna reinkann wenn er will, darum wird in der zeile 46 seine geduld also seine wartezeit wieder auf 3 sekunden gesetzt.

Problem: wenn der gast der grad aus der sauna raus ist aber wieder versuchen will in die sauna reinzugehen dann müßte ich für ihn nochmal die run methode aufrufen.
aber soweit ich weiß kann man einen thread nur einmal starten.
gibts denn eine möglichkeit wie ich es dennoch erreichen könnte das die run methode von diesem gast erneut gestartet wird?
 
G

Gast2

Gast
Moin,

Du kannst einen Thread nur einmal starten - richtig ... aber Du kannst einen neuen Thread für die selbe(n) Methoden starten ... und so der CPU-Gott will, hast Du bei allen Threads das gleiche deterministische Verhalten

hand, mogel
 

BlubBlub

Bekanntes Mitglied
ich hab beschlossen, dasss jeder gast nur einmal in die sauna darf ^^ damit erspar ich mir dieses eine problem ^^ ... trotzdem danke für den hinweis


in der aufgabenstellung stand:
"Schreiben Sie ein Programm, das in zufälligen Zeitabständen Personen-Objekte eines zufälligen Geschlechts erzeugt"

somit müßte ich ja die klasse "zugangskontrolle" zu einer unterklasse von Thread machen,
damit ich die methode sleep(sleeptime) verwenden kann um die zufälligen zeitabstände zu immitieren.

das hab ich gemacht, somit sieht meine klasse jetzt so aus:

Java:
public class Zugangskontrolle extends Thread
{

	public static void main(String[] args)
	{
		SaunaMonitor sauna = new SaunaMonitor();
		int besucheranzahl = 100; // zum bessere vergleich erstmal 100 besucher erzeugen 
		
		System.out.println("Kontrollausgabe(Besucheranzahl): " + besucheranzahl);
		
		for(int i = 1; i < besucheranzahl; i++)
		{
			try
			{
				sleep(4000); // ich hab erstmal 4 sekunden eingestellt anstelle einer zufälligen zeit
			}
			catch(InterruptedException e){}
			
			new Person(sauna, i).start();
		}
	}
}


das blöde daran ist, dass jetzt sowohl die klasse zugangskontrolle als auch die klasse person von der klasse thread erben. das stört mich ein wenig ,weil ich ja bei der klasse zugangskontrolle ja nur die zeit immer ein wenig anhalten will bevor weiter neue gäste produziert werden, fällt einem eine elegantere lösung ein?

zudem wollte ich, dass die ausgabe der texte auf die konsole auch nicht aufeinmal erfolgt sondern auch nur alle 3 sekunden, damit man das geschehen besser verfolgen kann. das alles erreicht ich nur mit der sleep() methode nicht wahr?
 
Zuletzt bearbeitet:

BlubBlub

Bekanntes Mitglied
Feeertig ^^ ... so ich glaub ich hab die aufgabe jetzt hingekriegt:

Et voila hier meine Lösung:

Java:
public class SaunaMonitor
{
	private int personenanzahl;
	private String geschlecht = "";
	
	public synchronized void goIn(Person gast) 
	{	
		while( !(geschlecht.equals(gast.getGeschlecht())) & (!(geschlecht.equals("")))  ) 
		{
			try
			{
				wait(); 
			}
			catch(InterruptedException e){}
		}
		
		this.geschlecht = gast.getGeschlecht();
			
		System.out.println("Eintritt in die Sauna von Gast Nr.: " + gast.getBesuchernummer() + " Geschlecht: " + gast.getGeschlecht()  
			           		+ " Verweilzeit: " + (gast.getVerweilzeit()/1000.0) + " Sekunden"); 
			
		personenanzahl++; 
		
		System.out.println("Personenanzahl in der Sauna: " + personenanzahl + "  Geschlecht: " + geschlecht);
		System.out.println("Personenanzahl vor der Sauna: " + (Zugangskontrolle.getWeiblicheBesucher() + Zugangskontrolle.getMaennlicheBesucher() - personenanzahl) );
		
		if(this.geschlecht.equals("w"))
			System.out.println("Davon weibliche: " + (Zugangskontrolle.getWeiblicheBesucher() - personenanzahl) + " und männliche: " + Zugangskontrolle.getMaennlicheBesucher());
		else
			System.out.println("Davon weibliche: " +  Zugangskontrolle.getWeiblicheBesucher()  + " und männliche: " + (Zugangskontrolle.getMaennlicheBesucher() - personenanzahl));
	
		System.out.println();
	}
	
	public synchronized void goOut(Person gast)
	{
		System.out.println("Verlassen der Sauna von Gast Nr.: " + gast.getBesuchernummer() + " Geschlecht: " + gast.getGeschlecht()
		                    + " Verweilte Zeit: " + (gast.getVerweilzeit()/1000.0) + " Sekunden"); 
		personenanzahl--; 
				
		if(personenanzahl == 0)
			this.geschlecht = "";
		
		System.out.println("Personenanzahl in der Sauna: " + personenanzahl + "  Geschlecht: " + geschlecht);
		System.out.println("Personenanzahl vor der Sauna: " + (Zugangskontrolle.getWeiblicheBesucher() + Zugangskontrolle.getMaennlicheBesucher() - personenanzahl) );
		
		if(this.geschlecht.equals("w"))
			System.out.println("Davon weibliche: " + (Zugangskontrolle.getWeiblicheBesucher() - personenanzahl) + " und männliche: " + Zugangskontrolle.getMaennlicheBesucher());
		else
			System.out.println("Davon weibliche: " +  Zugangskontrolle.getWeiblicheBesucher()  + " und männliche: " + (Zugangskontrolle.getMaennlicheBesucher() - personenanzahl));
		
		System.out.println();
		
		notifyAll(); 
	}
}

Java:
public class Person extends Thread
{
	private SaunaMonitor sauna;
	private String geschlecht;
	private int verweilzeit; 
	private int besuchernummer;
	
	public Person(SaunaMonitor sauna, int besuchernummer)
	{
		if((int)(Math.random()*10+1) > 5) 
		{	
			this.geschlecht = "w";	
			Zugangskontrolle.incrW();
		}
		else
		{	
			this.geschlecht = "m";
			Zugangskontrolle.incrM();
		}
	
		this.verweilzeit = (int)(Math.random()*10+1)*1000;  
		this.sauna = sauna;
		this.besuchernummer = besuchernummer;	
	}
	
	public void run()
	{
		sauna.goIn(this); 
		
		try
		{
			sleep(verweilzeit); 
		}
		catch(InterruptedException e){}
		
		sauna.goOut(this); 
	}
	
	public String getGeschlecht(){return geschlecht;}
	public int getVerweilzeit(){return verweilzeit;}
	public int getBesuchernummer(){return besuchernummer;}
}

Java:
public class Zugangskontrolle extends Thread
{
	private static int weiblicheBesucher;
	private static int maennlicheBesucher;
	private static int besucheranzahl;
	
	
	public static void main(String[] args)
	{
		SaunaMonitor sauna = new SaunaMonitor();
		besucheranzahl = (int)(Math.random()*20+1); 
		
		System.out.println("Kontrollausgabe(Besucheranzahl): " + besucheranzahl);
		System.out.println();
		
		for(int i = 1; i <= besucheranzahl; i++)
		{
			try
			{
				sleep((int)(Math.random()*5+1)*1000);
			}
			catch(InterruptedException e){}
			
			System.out.println("Ein Neuer Besucher betritt das Schwimmbad! (Besucher im Schwimmbad jetzt insgesamt: " + i + ")");
			System.out.println();
			new Person(sauna, i).start();
		}
	}
	
	public static void incrW(){weiblicheBesucher++;}
	public static void incrM(){maennlicheBesucher++;}
	public static int getWeiblicheBesucher(){return weiblicheBesucher;}
	public static int getMaennlicheBesucher(){return maennlicheBesucher;}
}


und noch eine beispiel ausgabe:

Kontrollausgabe(Besucheranzahl): 4

Ein Neuer Besucher betritt das Schwimmbad! (Besucher im Schwimmbad jetzt insgesamt: 1)

Eintritt in die Sauna von Gast Nr.: 1 Geschlecht: m Verweilzeit: 2.0 Sekunden
Personenanzahl in der Sauna: 1 Geschlecht: m
Personenanzahl vor der Sauna: 0
Davon weibliche: 0 und männliche: 0

Ein Neuer Besucher betritt das Schwimmbad! (Besucher im Schwimmbad jetzt insgesamt: 2)

Verlassen der Sauna von Gast Nr.: 1 Geschlecht: m Verweilte Zeit: 2.0 Sekunden
Personenanzahl in der Sauna: 0 Geschlecht:
Personenanzahl vor der Sauna: 2
Davon weibliche: 0 und männliche: 2

Eintritt in die Sauna von Gast Nr.: 2 Geschlecht: m Verweilzeit: 5.0 Sekunden
Personenanzahl in der Sauna: 1 Geschlecht: m
Personenanzahl vor der Sauna: 1
Davon weibliche: 0 und männliche: 1

Ein Neuer Besucher betritt das Schwimmbad! (Besucher im Schwimmbad jetzt insgesamt: 3)

Verlassen der Sauna von Gast Nr.: 2 Geschlecht: m Verweilte Zeit: 5.0 Sekunden
Personenanzahl in der Sauna: 0 Geschlecht:
Personenanzahl vor der Sauna: 3
Davon weibliche: 1 und männliche: 2

Eintritt in die Sauna von Gast Nr.: 3 Geschlecht: w Verweilzeit: 7.0 Sekunden
Personenanzahl in der Sauna: 1 Geschlecht: w
Personenanzahl vor der Sauna: 2
Davon weibliche: 0 und männliche: 2

Ein Neuer Besucher betritt das Schwimmbad! (Besucher im Schwimmbad jetzt insgesamt: 4)

Verlassen der Sauna von Gast Nr.: 3 Geschlecht: w Verweilte Zeit: 7.0 Sekunden
Personenanzahl in der Sauna: 0 Geschlecht:
Personenanzahl vor der Sauna: 4
Davon weibliche: 1 und männliche: 3

Eintritt in die Sauna von Gast Nr.: 4 Geschlecht: m Verweilzeit: 7.0 Sekunden
Personenanzahl in der Sauna: 1 Geschlecht: m
Personenanzahl vor der Sauna: 3
Davon weibliche: 1 und männliche: 2

Verlassen der Sauna von Gast Nr.: 4 Geschlecht: m Verweilte Zeit: 7.0 Sekunden
Personenanzahl in der Sauna: 0 Geschlecht:
Personenanzahl vor der Sauna: 4
Davon weibliche: 1 und männliche: 3

----------------------------------------------------------------------------------

und an dieser stelle möchte ich mich noch bei den helfern hier bedanken, die mir tipps gegeben haben.

p.s. ich hab jetzt mehrmals das programm ausprobiert, aber es kam niemals zu einem deadlock, obwohl in der anmerkung steht das dies passieren könnte, weiß jemand wann so ein fall eintretten könnte in bezug auf dieses beispiel?
 
Zuletzt bearbeitet:
S

SlaterB

Gast
in der Aufgabenstellung steht nichts von DeadLock, sondern 'nie Wechsel',
z.B. weil so viele Personen kommen, dass zu jedem Zeitpunkt etwa 100 von einer Gruppe drin sind, und 100 andere warten,
durch die Menge der neuen Leute ist ein Wechsel quasi ausgeschlossen,
außer, es kommt mit Wahrscheinlichkeit 1:2^ganzViel eine Zeit lang nur Personen der anderen Gruppe,

was man dagegen tun will, ist mir unklar, außer manuell zu sagen: 'so jetzt eine Zeit lang keine Männer mehr rein'
 
Zuletzt bearbeitet von einem Moderator:
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Ausgabe auf der Konsole bei Nebenläufigkeit, Threads und Synchronisation Allgemeine Java-Themen 8
F Threads - Nebenläufigkeit Allgemeine Java-Themen 6
M Threads und Nebenläufigkeit Allgemeine Java-Themen 9
K Threads Nebenläufigkeit - Busy Waiting: Exotisches Problem Allgemeine Java-Themen 5
F Frage zu Nebenläufigkeit Allgemeine Java-Themen 15
rode45e Java Threads Allgemeine Java-Themen 4
M Threads Allgemeine Java-Themen 1
L Threads Threads in Chatroom Allgemeine Java-Themen 30
berserkerdq2 run-methode eines Threads so programmieren, dass 30x die Sekunde etwas ausgeführt wird. Allgemeine Java-Themen 44
berserkerdq2 Threads, wie genau läuft das in Java ab? (Ich kann Threads erstellen und nutzen, nur das Verständnis) Allgemeine Java-Themen 6
CptK Backpropagation parallelisieren: Kommunikation zwischen den Threads Allgemeine Java-Themen 7
J Eine Frage zu den Threads und Task Allgemeine Java-Themen 1
W Wieviele Threads sind sinnvoll? Allgemeine Java-Themen 8
W Alternative für Threads Allgemeine Java-Themen 6
V Threads Probleme beim Aufrufen von Methoden einer anderen Klasse (Threads) Allgemeine Java-Themen 14
T Multithreading: Wie viele Threads sollte ich erstellen? Allgemeine Java-Themen 12
G Threads vom Mainprogramm steuern Allgemeine Java-Themen 8
S BlockingQueue mit dynamischer Anpassung der Anzahl von Producer und Consumer Threads Allgemeine Java-Themen 1
x46 Threads Threads anhalten Allgemeine Java-Themen 1
J Threads verbessern die Performance NICHT ? Allgemeine Java-Themen 8
W Threads Problem Allgemeine Java-Themen 15
T Threads Tic Tac Toe mit Threads Allgemeine Java-Themen 1
M Threads über Kommandozeile Allgemeine Java-Themen 5
mrbig2017 Threads Chat Programm mit Threads? Allgemeine Java-Themen 2
J Threads - java.lang.IllegalThreadStateException Allgemeine Java-Themen 6
J Internet Broswer in Threads öffnen Allgemeine Java-Themen 1
B Threads Multithreading Threads sollen warten Allgemeine Java-Themen 12
N 1000 MQTT Messages die Sekunde - 1000 Threads erstellen ? Allgemeine Java-Themen 10
D Threads Parallel laufende Threads Allgemeine Java-Themen 4
J Unvorhersehbares Verhalten - benutze ich die falsche Bedingungsprüfung oder brauche ich Threads? Allgemeine Java-Themen 12
D Eine Forschleife mit Threads abarbeiten um es zu schneller zu machen. Ist das möglich? Allgemeine Java-Themen 20
S Wie kann ich eine kleine Stelle in meinem Code mit multiplen Threads abarbeiten..? Allgemeine Java-Themen 20
P Threads Parallelisierte DB-Abfragen mit variabler Anzahl an Threads Allgemeine Java-Themen 4
J Threads Threads Allgemeine Java-Themen 9
Viktim Threads Liste In unterschiedlichen Threads bearbeiten Allgemeine Java-Themen 23
E Threads Ausführung in Threads ist langsamer als ohne Threads Allgemeine Java-Themen 13
A Anzahl an Threads Systemweit Allgemeine Java-Themen 2
Tausendsassa Input/Output Problem mit der gleichzeitigen Ausgabe zweier Threads Allgemeine Java-Themen 8
S Alle Methodenaufrufe eines Threads notieren..? Allgemeine Java-Themen 7
M Threads JPanel eingeforen mit Threads Allgemeine Java-Themen 2
F Threads Allgemeine Java-Themen 6
F Threads Allgemeine Java-Themen 2
M Sinn von Threads? Allgemeine Java-Themen 1
J Wie erschaffe ich einen sicheren Datenaustausch zwischen Thread und Nicht-Threads Allgemeine Java-Themen 8
L Abfragen ob Threads fertig Allgemeine Java-Themen 3
P Threads Java Zugreifen Allgemeine Java-Themen 6
K Problem: Java-Klasse mit mehreren Threads als eigenen Prozess starten Allgemeine Java-Themen 3
K KeyEvent in Threads Allgemeine Java-Themen 11
V Threads Weshalb funktionieren meine Threads nicht? Allgemeine Java-Themen 2
Thallius Speicherverhalten von Properties und mehreren Threads Allgemeine Java-Themen 5
L Threads beenden Allgemeine Java-Themen 4
P Threads Threads nicht gleichzeitig starten Allgemeine Java-Themen 3
S Threads Threads werden nicht beendet Allgemeine Java-Themen 2
S Start des zweiten Threads erst nach Beenden des ersten Threads Allgemeine Java-Themen 13
N Threads statische Methoden in Threads Allgemeine Java-Themen 5
P 4 Threads in einer Methode Allgemeine Java-Themen 2
M Eclipse Mehrere Threads, mehrere Konsolen Allgemeine Java-Themen 4
OnDemand Threads und synchronized Allgemeine Java-Themen 9
R LinkedList und Threads: Strukturprobleme bez. löschen von Elementen Allgemeine Java-Themen 3
R LinkedList und Threads - welche Methode ist besser? Allgemeine Java-Themen 2
OnDemand Threads und synvhronized Allgemeine Java-Themen 2
S Problem mit Threads Allgemeine Java-Themen 1
W Threads Threads warten lassen Allgemeine Java-Themen 5
H Optimierung durch Threads Allgemeine Java-Themen 31
B Threads halten sich irgendwie auf... Allgemeine Java-Themen 6
M Threads Allgemeine Java-Themen 8
K JNI: Methoden aus unterschiedlichen Threads aufrufen Allgemeine Java-Themen 3
A Applet Alle Threads beim schließen des Applets beenden Allgemeine Java-Themen 8
A Problem mit der Synchronisierung von Threads Allgemeine Java-Themen 15
R SecurityManager für einzelne Klassen/Threads? Allgemeine Java-Themen 38
O Threads und If Befehle Allgemeine Java-Themen 7
P Threads abwechseln lassen mit wait() und notify() Allgemeine Java-Themen 2
H Sehr viele Threads effizient Verwalten Allgemeine Java-Themen 13
C Threads und Exceptions Allgemeine Java-Themen 7
H java.lang.OutOfMemoryError bei der wiederholten Erzeugng von Threads Allgemeine Java-Themen 8
S Threads Abarbeitungsstatus von Threads in Datei schreiben Allgemeine Java-Themen 2
M Zugriff zweier Threads auf diesselbe Methode Allgemeine Java-Themen 16
E Threads Sudoku Threads Allgemeine Java-Themen 8
M Java Threads - Wait Notify - Verständnisproblem Allgemeine Java-Themen 5
Gossi Threads mit unterschiedlichen Aufgaben in einer Klasse? Allgemeine Java-Themen 9
G Threads Ablauf von Threads im Spezialfall Allgemeine Java-Themen 4
V Threads bei quadcore Allgemeine Java-Themen 10
V 1000 Threads oder Iterativ? Allgemeine Java-Themen 11
4 Simple(?) Frage zu Threads Allgemeine Java-Themen 14
B Threads Game of Life - Threads Allgemeine Java-Themen 49
R Threads Exceptions von Threads abfangen im ThreadPool Allgemeine Java-Themen 5
S Threads Ende sämtlicher Threads abwarten Allgemeine Java-Themen 6
S Frage zu Threads (Sichtbarkeit und Verhalten) Allgemeine Java-Themen 11
M Java-Threads und Datentypen-Zugriffe Allgemeine Java-Themen 7
P Threads- Programming Allgemeine Java-Themen 2
G Threads Klasse Sound und Threads bleiben hängen Allgemeine Java-Themen 4
C Threads Zwei Threads greifen auf LinkedList zu. Allgemeine Java-Themen 12
M OutOfMemoryError in nebenläufigen Threads Allgemeine Java-Themen 6
M Threads dauerhafte bewegung mit threads Allgemeine Java-Themen 11
frankred Threads Auf eine Gruppe von Threads warten Allgemeine Java-Themen 11
J Eure Meinung: Threads verwenden, oder nicht? Allgemeine Java-Themen 6
K Warum wartet diese Funktion auf beenden des Threads? Allgemeine Java-Themen 3
F Mehrere Threads - ein Stack Allgemeine Java-Themen 6
O Wie kann ich das Ende eines Threads melden? Allgemeine Java-Themen 7
J Writer und Threads Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben