Arzt - Patienten [ Threads ]

Die run methode die ich dir empfohlen habe, sollte jene von dem Patienten sein und nicht so wie du es jetzt hast die von dem Behandlungsraum

deine registrieren Methode des Behandlungsraums ist auch falsch. wozu brauchst du dort eine Dauerschleife (auch wenn durch das return die schleife nur einmal ausgeführt wird)?

gib die Schleife einfach weg nur der Code der in der schleife ausgeführt wird ist wichtig.

Hat dann nicht jeder Patient die gleiche Wartenummer ?

Ausgabe:


Nummer 0 bitte.
Nummer 0 bitte.
Nummer 0 betritt den Raum.
Nummer 0 betritt den Raum.
Der Raum ist frei.
Patient nr.0 verlässt den Raum.


Der Raum ist leider besetzt.


public class Terminal {

	public static void main(String[] args) throws InterruptedException 
	
	{
	  final Behandlungsraum b = new Behandlungsraum();
	  Patient p1 = new Patient(b);
	  Patient p2 = new Patient(b);
	  
	 Thread t2 = new Thread(p1);
	 Thread t3 = new Thread(p2);
	 
	 t2.start();
	 t3.start();

	 t2.join();
	 t3.join();
	}

}

public class Behandlungsraum

{
	private static int wartenummer = 0;
	Random r = new Random();
	private Object lock = new Object();
    private boolean besetzt = false;
    
   
	public int registrieren() throws InterruptedException // Gibt die nächste Wartenummer zurück
	                                                      // Wer als nächstes dran ist.
	    {		    			
			Thread.sleep(r.nextInt(5000)+3000);	
	        System.out.println("Nummer " + wartenummer + " bitte.");	        
			return wartenummer;									
		}
	
		
	public void betreten(int nummer) throws InterruptedException
	{
		System.out.println("Nummer " + wartenummer + " betritt den Raum.");	 
			synchronized(lock)
			{
				while (istBesetzt() || wartenummer != nummer)
				{
					System.out.println("
"  + "Der Raum ist leider besetzt." + "
" );
					lock.wait();			
				}			
				System.out.println("Der Raum ist frei.");
				Thread.sleep(500);
				besetze();
				wartenummer++;
			}
	
		
	}

	public void verlasse() throws InterruptedException
	{
		synchronized(lock)
		{			
			Thread.sleep(500);
				int b = wartenummer - 1;
				System.out.println("Patient nr." + b + " verlässt den Raum." + "
");
				besetzt = false;		
				lock.notifyAll();		
		}
		
		
	}	
	

	public void besetze()
	{
		besetzt = true;
	}
	public boolean istBesetzt()
	{
		return besetzt;
	}
	
				
					
			
}
	
		
		
	
	

	{		

	private Behandlungsraum behandlungsraum;
    private int wartenummer;
    
	public Patient(Behandlungsraum b) throws InterruptedException
	{
		behandlungsraum = b;
		wartenummer = behandlungsraum.registrieren();
	}
	
		public void run() 
		
		{
			
			try {
				behandlungsraum.betreten(wartenummer);
				behandlungsraum.verlasse();
			} 
			catch (InterruptedException e)
			{
			
			}
		}
		
	}

du kannst ja in der registrieren-Methode die wartenummer um 1 erhöhen?..
nebenbei: wenn vermeidbar, dann nicht statisch machen, damit auch zwei verschiedene Behandlungsräume gleichzeitig denkbar sind

registrieren()-Aufruf wie gesagt in run-Methode des Patienten, sonst ist die main-Methode lange beschäftigt die Patient-Objekte anzulegen

betreten() verwendet die wartenummer-Variable auch für Zugriffskontrolle, das sollten verschiedene Variablen sein,
wenn gerade Nummer 12 ausgeteilt wird (irgendjemand muss das ja verwalten) und 5 Leute warten, ist gerade Nummer 7 oder so zur Behandlung dran

Du musst im Behandlungsraum zwei verschiedene Nummern merken.

Die erste ist die gezogene Nummer. Dh. Patient a kommt zum Behandlungsraum registriet sich. während dieser registreireung wird die gezogene nummer um ein erhöht und dem Patienten mitgeteilt (return value) der nächste patient kommt zum Behandlungsraum registriert sich und bekommt nun die nächste Freie nummer und der Behandlungsraum zählt wieder eins weiter.

Wichtig hier wieder: Der Behandlungsraum weiß welche Nummer als nächstes gezogen wird.

Die zweite Nummer die der Behandlungsraum speichern muss ist jene die als nächstes behandelt wird.
die muss immer hochgezählt werden, wenn der Patient die Behandlung verlässt.

Was bei dir jetzt fürs erste noch fehlt beim Registrieren, ist das Hochzählen der Nummer die als nächstes zurückgegeben wird.

Nur als tipp. zur Zeit holst du dir die Wartenummer im Konstruktor deines Patienten. Das wird zwar zu einem funktionierenden Ablauf führen, passt aber meiner Meinung nicht ganz zur Aufgabenstellung. Das registrieren sollte auch im Patienten Thread ausgeführt werden, also in der run-Methode als erster Befehl.

:confused:

Ausgabe:

Nummer  1 will den Raum betreten.
Nummer  1 betritt den Raum.
Nummer 2 registriert.
Nummer  2 will den Raum betreten.

Der Raum ist leider besetzt.

Nummer 3 registriert.
Nummer  3 will den Raum betreten.
Nummer 4 registriert.
Nummer  4 will den Raum betreten.
Patient nr.4 verlässt den Raum.

Nummer  2 betritt den Raum.

Der Raum ist leider besetzt.


Der Raum ist leider besetzt.

Patient nr.4 verlässt den Raum.

Nummer  3 betritt den Raum.
Patient nr.4 verlässt den Raum.

Nummer  4 betritt den Raum.
Patient nr.4 verlässt den Raum.

Nummer 5 registriert.
Nummer  5 will den Raum betreten.
Nummer  5 betritt den Raum.
Nummer 6 registriert.
Nummer  6 will den Raum betreten.
Patient nr.6 verlässt den Raum.

Nummer  6 betritt den Raum.
Patient nr.6 verlässt den Raum.



public class Behandlungsraum

{
	private int wartenummer;
	private int nummer;
	Random r = new Random();
	private Object lock = new Object();
    private boolean besetzt = false;
    
   
	public int registrieren() throws InterruptedException 
	    {		 		
			Thread.sleep(r.nextInt(5000)+3000);	          // Registrierung dauert 3-8 Sekunden    
			nummer++;                                     // Die letzte gezogene Nummer + 1
	        System.out.println("Nummer " + nummer + " registriert.");	   	                                           
			return nummer;								  // Die Nummer die der nächste Patient zieht
		}
	
		
	public void betreten(int nummer) throws InterruptedException
	{
		System.out.println("Nummer  " + nummer + " will den Raum betreten.");	 
			synchronized(lock)
			{
				if (istBesetzt())
				{
					System.out.println("
"  + "Der Raum ist leider besetzt." + "
" );
					lock.wait();			
				}		
				else if (wartenummer != nummer)
				{
					lock.notifyAll();
				}
				System.out.println("Nummer  " + nummer + " betritt den Raum.");	 				
				Thread.sleep(500);
				besetze();
                wartenummer++;
			}
	
		
	}

	public void verlasse() throws InterruptedException
	{
		synchronized(lock)
		{			
			    Thread.sleep(500);;
				System.out.println("Patient nr." + nummer + " verlässt den Raum." + "
");
				besetzt = false;		
				lock.notifyAll();		
		}
		
		
	}	
	

	public void besetze()
	{
		besetzt = true;
	}
	public boolean istBesetzt()
	{
		return besetzt;
	}
	
				
					
			
}
	
		
		
	
	


public class Patient implements Runnable
	{		

	private Behandlungsraum behandlungsraum;
    private int wartenummer;
    
	public Patient(Behandlungsraum b) throws InterruptedException
	{
		behandlungsraum = b;
		
	}
	
		public void run() 
		
		{
			
			try {
				wartenummer = behandlungsraum.registrieren();
				behandlungsraum.betreten(wartenummer);
				behandlungsraum.verlasse();
			} 
			catch (InterruptedException e)
			{
			
			}
		}
		
	}

und was ist das Problem am Log bzw. was missfällt dir?
der Fehler ist ja so unendlich offensichtlich, aber das hilft langsam nicht mehr, wenn andere für dich programmieren

was genau gefällt dir am Log nicht, welche Methode ist betroffen, was genau wird dort an Informationen von welchen Objekten benutzt,
kannst du für alles kurz kritisch hintertragen ob so korrekt?
woher könnten falsche Werte stattdessen kommen, werden ja sicher nicht ausgedacht, an anderer Stelle bekannt?

dass der Parameter von betreten() genauso heißt wie das Attribut für die registrieren-Methode ist nicht der Fehler, aber auch so schon haarsträubend,
muss doch nicht alles durcheinander gehen

es sollte ohne notifyAll() in betreten() funktionieren, Thread werden nur durch besetze Behandlungszimmer aufgehalten, dafür gibt es immer auch ein notifyAll() in verlassen()


die Registrierung sollte übrigens auch synchronisiert werden, nicht dass da zwei Threads durcheinander drin sind,
erst für beide Nummer erhöht, dann bekommen beide dieselbe nun aktuelle Nummer

Ich habs jetzt komplett neu geschrieben einmal.
Der Fehler war bei der verlassen methode…


public class Behandlungsraum 
{
  private int wartenummer;  // auszugebende Wartenummer
  private int aktuellaufgerufenenummer; // aktuell aufgerufene Nummer
  private boolean istbesetzt; // Status "besetzt"
  private Object lock = new Object(); // Lock object
  
  public int registrieren()
  {	  
	                          // warte 3-8 Sekunden  
	return wartenummer++;	  // liefert die nächste Wartenummer
  }
  
  void betreten(int nummer) throws InterruptedException
  {
	  synchronized(lock)
	  {
	  if(istbesetzt)
	  {
		  lock.wait();             // Warte falls der Raum besetzt sein sollte
	  }
	  else if(wartenummer != nummer)
	  {
		  lock.wait();             // Warte die eigene Wartenummer nicht mit der aufgerufenen Nummer übereinstimmt.
	  }
	  
	  istbesetzt = true;      // Der Raum als besetzt gekennzeichnet 
	  aktuellaufgerufenenummer++; // aufgerufene Nummer um 1 erhöht. 
	  }
  }
  
  
  public void verlassen() throws InterruptedException
  {
	  
	  while(!istbesetzt)
	  {
	                              // Niemand verlässt den Raum, weil auch keiner im Raum ist
	  }
	  istbesetzt = false;         //  der Raum wird freigegeben
	  lock.notifyAll();           //  alle wartenden Threads werden geweckt. 
  }
  
	
}

ein grober Neuanfang, eine Skizze?
erstaunlich wenn damit Fehler gefunden, ist ja nicht lauffähig (zuvor schon falsch geraten, aber notifyAll() in verlassen ohne synchronized wieder, aber das könnte ja auch erst noch später dazugekommen sein)

die while(!istbesetzt)-Schleife in verlassen() ist aber in jedem Fall bedenklich,
hat in keiner Stufe etwas darin zu suchen, war vorher auch nicht dabei,

Grund für Neueinfügen? jede Schleife nur mit Bedingung, nur mit Warten auf Nebenläufigkeit, ist bedenkenswert, läuft millionenmal pro Sekunde, eine CPU schmilzt bei 100%,
evtl. ist das Stromnetz, ganz Deutschland, das ganze Universum gefährdet (ok, so schlimm doch nicht :wink: trotzdem vermeiden)

fachlich hier auch nicht nötig, es hat keinen Zweck zu warten, bis jemand anders (wer?) besetzt und dann selber (wer bin ich?) den Raum freizugeben,
nur damit dann der andere bei seinem Verlassen wieder selber warten muss bis wer anders kommt,

erinnert nebenbei dass vielleicht besser zu prüfen ist, wer der Aufrufer von verlassen() ist, hoffentlich nur der Patient, der auch gerade drin ist

EDIT:

?

aber Code so besser ?

Ausgabe:

Ein Patient wird behandelt[...] o
Patient hat Nummer 2 gezogen. o
Patient hat Nummer 3 gezogen. o
Patient hat Nummer 4 gezogen. o
Patient hat Nummer 5 gezogen. o 
Patient hat Nummer 6 gezogen. o
Während ein Patient versuchte den Raum zu betreten ist er leider besetzt. o
Während ein Patient versuchte den Raum zu betreten ist er leider besetzt. o
Während ein Patient versuchte den Raum zu betreten ist er leider besetzt. o
Während ein Patient versuchte den Raum zu betreten ist er leider besetzt. o
Während ein Patient versuchte den Raum zu betreten ist er leider besetzt. o
Ein Patient hat den Raum verlassen. o
Ein Patient wird behandelt[...] o
Während ein Patient versuchte den Raum zu betreten ist er leider besetzt. o
Während ein Patient versuchte den Raum zu betreten ist er leider besetzt. o
Während ein Patient versuchte den Raum zu betreten ist er leider besetzt. o
Während ein Patient versuchte den Raum zu betreten ist er leider besetzt. o
Ein Patient hat den Raum verlassen. o 
Ein Patient ohne die richtige Nummer wollte den Raum betreten.
Ein Patient ohne die richtige Nummer wollte den Raum betreten.
Ein Patient ohne die richtige Nummer wollte den Raum betreten.
Ein Patient wird behandelt[...]
Ein Patient hat den Raum verlassen.
Ein Patient wird behandelt[...]
Ein Patient hat den Raum verlassen.
Ein Patient wird behandelt[...]
Ein Patient hat den Raum verlassen.
Ein Patient wird behandelt[...]
Ein Patient hat den Raum verlassen.


public class Behandlungsraum 
{
  import java.util.Random;


public class Behandlungsraum 
{
  private int wartenummer;  // auszugebende Wartenummer
  private int aktuellaufgerufenenummer = 1; // aktuell aufgerufene Nummer
  private boolean istbesetzt; // Status "besetzt"
  private Object lock = new Object(); // Lock object
  private Random random = new Random();
  
  public int registrieren() throws InterruptedException
  {	  	
	   Thread.sleep(random.nextInt(5000)+3000);     // warte 3-8 Sekunden  
	   System.out.println("Patient hat Nummer " + ((wartenummer) + 1) + " gezogen.");		
	   wartenummer++;
	  return wartenummer;	                     // liefert die nächste Wartenummer
  }
  
  public void betreten(int nummer) throws InterruptedException
  {
	  synchronized(lock)
	  {
	  while(istbesetzt)
	  {
		  System.out.println("Während ein Patient versuchte den Raum zu betreten ist er leider besetzt.");
		  lock.wait();             // Warte falls der Raum besetzt sein sollte
	  }
	  while(aktuellaufgerufenenummer != nummer)
	  {

		 System.out.println("Ein Patient ohne die richtige Nummer wollte den Raum betreten.");			
		  lock.wait();                       // Warte die eigene Wartenummer nicht mit der aufgerufenen Nummer übereinstimmt.
	  }
	  System.out.println("Ein Patient wird behandelt[...]");					
	  istbesetzt = true;      // Der Raum als besetzt gekennzeichnet 	  
	  aktuellaufgerufenenummer++; // aufgerufene Nummer um 1 erhöht. 
	  Thread.sleep(5000);     // Patient wird behandelt
	  }
  }
  
  
  public void verlassen() throws InterruptedException
  {
	  synchronized(lock)
	  {
		  System.out.println("Ein Patient hat den Raum verlassen.");			
		  istbesetzt = false;         //  der Raum wird freigegeben
		  lock.notifyAll();           //  alle wartenden Threads werden geweckt.  
	  }
	
  }
  
	
}

gegen das theoretische Problem gleichzeitiger Registrierung hilft synchronized, auch damit immer nur einer die 3-8 sec belegen kann, realistischer,
nicht mit dem Wartezimmer-Lock

das mit den Meldungen sehe ich als korrekt an, wenn so viel gleichzeitig warten, dann ist das eben so, es hilft vielleicht das obige, längere Warten,
aber wieder an der Realität messen, wenn 5 da sind und alle aufspringen, dann ist das so

ein konkretes Problem kann ich gerade nicht sehen, das muss aber keine Garantie sein

ruhig auch wieder in den weiteren Ausgaben dazu schreiben, welcher Patient den Raum verläßt usw.,
zuvor war dabei ein Fehler, die Info wegzulassen ist dann etwas billig,
aber ob nun bei der Aufgabe wichtig ist Interpretation

Es war ein sehr kleiner dummer Fehler drin, wo ich einfach zwei Variablen vertauscht hatte. Also die Wartenummer und die Aufzurufende Nummer.
Sleep Timer besser eingebaut und die while schleife hatt sich an den falschen Nummer aufgehängt ?

Diese Ausgabe ist richtig und das was verlangt war, manchmal jedoch ( müsste an den sleeps liegen ? ) kriege ich ein falsches Ergebniss ? :o

Ausgabe ist :

Patient 1 wird behandelt[...]
Patient hat Nummer 2 gezogen.
Patient hat Nummer 3 gezogen.
Patient hat Nummer 4 gezogen.
Patient hat Nummer 5 gezogen.
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Patient hat Nummer 6 gezogen.
Ein Patient hat den Raum verlassen.
Patient 2 wird behandelt[...]
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Ein Patient hat den Raum verlassen.
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Patient 3 wird behandelt[...]
Ein Patient hat den Raum verlassen.
Patient 4 wird behandelt[...]
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Ein Patient hat den Raum verlassen.
Patienten befinden sich noch im Wartezimmer.
Patient 5 wird behandelt[...]
Ein Patient hat den Raum verlassen.
Patient 6 wird behandelt[...]
Ein Patient hat den Raum verlassen.

Code ist



public class Behandlungsraum 
{
  private int wartenummer;  // auszugebende Wartenummer
  private int aktuellaufgerufenenummer = 1; // aktuell aufgerufene Nummer
  private boolean istbesetzt; // Status "besetzt"
  private Object lock = new Object(); // Lock object
  private Random random = new Random();
  
  public int registrieren() throws InterruptedException
  {	  	
	   Thread.sleep(random.nextInt(5000)+3000);     // warte 3-8 Sekunden  
	   System.out.println("Patient hat Nummer " + ((wartenummer) + 1) + " gezogen.");		
	   wartenummer++;
	  return wartenummer;	                     // liefert die nächste Wartenummer
  }
  
  public void betreten(int nummer) throws InterruptedException
  {
	  synchronized(lock)
	  {
	  while(istbesetzt || aktuellaufgerufenenummer != nummer )
	  {
		  System.out.println("Patienten befinden sich noch im Wartezimmer.");
		  lock.wait();             // Warte falls der Raum besetzt sein sollte
	  }
	
	  Thread.sleep(100);      // Patient betritt den Raum
	  istbesetzt = true;      // Der Raum als besetzt gekennzeichnet 	
	  System.out.println("Patient " + aktuellaufgerufenenummer + " wird behandelt[...]");					
	  aktuellaufgerufenenummer++; // aufgerufene Nummer um 1 erhöht. 
	  Thread.sleep(4000);     // Patient wird behandelt
	  }
  }
  
  
  public void verlassen() throws InterruptedException
  {
	  synchronized(lock)
	  {
          Thread.sleep(300);
		  System.out.println("Ein Patient hat den Raum verlassen.");			
		  istbesetzt = false;         //  der Raum wird freigegeben
		  lock.notifyAll();           //  alle wartenden Threads werden geweckt.  
	  }
	
  }
  
	
}

ich wuerde diese Zeile noch in die Verlassen methode stellen. Macht von der logik mehr sinn, da erst wenn der Raum verlassen wird der naechst Patient aufgerufen werden kann.
(ist aber eher nur ein Schoenheitsfehler).

das Thema ist als Gelöst markiert, was nicht zum letzten Posting von Quiji passt, immer etwas ungünstig,
falls es anders stehen sollte, dann Bescheid sagen

Patient hat Nummer 1 gezogen.
Patient 1 wird behandelt[…]
Patient hat Nummer 2 gezogen.
Patient hat Nummer 3 gezogen.
Patient hat Nummer 4 gezogen.
Patient hat Nummer 5 gezogen.
Patient hat Nummer 6 gezogen.
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Ein Patient hat den Raum verlassen.
Patient 2 wird behandelt[…]
Ein Patient hat den Raum verlassen.
Patient 3 wird behandelt[…]
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Ein Patient hat den Raum verlassen.
Patienten befinden sich noch im Wartezimmer.
Patienten befinden sich noch im Wartezimmer.
Patient 4 wird behandelt[…]
Ein Patient hat den Raum verlassen.
Patient 5 wird behandelt[…]
Patienten befinden sich noch im Wartezimmer.
Ein Patient hat den Raum verlassen.
Patient 6 wird behandelt[…]

Die Ausgabe ist manchmal etwas Merkwürdig…
Patient 2 verlässt den Raum und Patient 3 betritt den Raum alleine ohne das die anderen Patienten es versuchen ?
Oder liegt das daran das Patient 3 es zu erst versucht.

warum sollte der Fall, dass Patient 3 es zu erst versucht, nicht kommen,
im Zweifel noch mehr Logausgaben a la ‘Patient x beendet sein Warten der Art …, wird gleich wieder …’, aber kommt sicher aufs Gleiche hinaus,
Patient 3 eben mal erster, man sieht ja auch die Ausgaben der anderen noch dahinter,

beim nächsten Mal ist Patient 4 erst der Dritte usw.,
wäre aber auch nicht zu ungewöhnlich falls meist in Reihenfolge aktiviert, einfach nichts erwarten,
wichtig ist, dass die wichtigen Dinge funktionieren: gegenseitiger Ausschluss durch Synchronisation, wartende Threads die später noch drankommen usw.

Detail am Rande:
System.out.println()-Ausgabe sind (glaube ich) vergleichsweise aufwendig ist, und ob synchronisiert…, können manches verfälschen, zumindest Reihenfolge der Ausgaben,
chirurgisch genauer wäre es evtl., nur Strings in eine statische Log-Liste synchronisiert einzufügen, und am Ende des zu betrachtenden Zeitraums alle auszugeben,
im Normalfall und für diese Aufgabe aber nicht relevant

Das mit den Logs hab ich jetzt schon öfters gesehen. Gibt es dazu vorhergesehene Klassen oder soll ich einfach meine eiene für “immer” benutzen ?

was du privat machst steht dir frei, sprichst du von log4j & Co.?
da gibt es sicher einiges und leicht zu finden, Fachbegriffe Log + Logger…,
schreiben aber evtl. auch an Konsole oder Datei, muss nicht besser sein als System.out.println() zu dem was ich vermutet hatte

für eine Aufgabe zur Abgabe besser nichts komplizierteres als System.out.println(), es sei denn anders vereinbart

So, darf die Aufgabe hier im Internet geschrieben werden?

Ich hab das mal für dich gemacht, noch zu verbessern, wie ich mir das vorstelle:

 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package dasisttest;

/**
 * @author CB at FBW.net
 */
public class DasIstTest {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Raum raum = new Raum();
        //for (int i = 0; i < 11; i++) {
        new Pati("", raum)                      .start();
        new Pati("Leon", raum)                  .start();
        new Pati("Lukas / Lucas", raum)         .start();
        new Pati("Ben", raum)                   .start();
        new Pati("Finn / Fynn", raum)           .start();
        new Pati("Jonas", raum)                 .start();
        new Pati("Paul", raum)                  .start();
        new Pati("Luis / Louis", raum)          .start();
        new Pati("Maximilian", raum)            .start();
        new Pati("Luca / Luka", raum)           .start();
        new Pati("Felix", raum)                 .start();
        new Pati("Tim", raum)                   .start();
        //}
    }
}```
Quelle: www beliebte vornamen de, 2010

```/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package dasisttest;

/**
 * @author CB at FBW.net
 */
public class Pati extends Thread {

    private String name = "oh";
    private Raum r;

    public Pati(String name, Raum r) {
        // null nicht vergessen
        this.name = name;
        this.r = r;
    }

    @Override
    public void run() {
        try {
            int id = r.registrieren(this);
            Thread.sleep((int) (Math.random() * 5001) + 3000);
            r.betreten(id);
            Thread.sleep((int) (Math.random() * 5001) + 3000);
            r.verlassen(id);
            Thread.sleep((int) (Math.random() * 5001) + 3000);
            System.out.println(name + id + " wurde behandelt.");
        } catch (InterruptedException interruptedException) {
            interruptedException.printStackTrace();
        }
    }
}```

```/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package dasisttest;

import java.util.UUID;

/**
 * @author CB at FBW.net
 */
public class Raum {

    private boolean besetzt = false;

    public synchronized int registrieren(Pati p) {
        System.out.println(p + " hat sich registriert (und wartet).");
        return UUID.randomUUID().hashCode();
    }

    public synchronized boolean betreten(int id) throws InterruptedException {
        System.out.println(id + " möchte Raum betreten und wartet.");
        while (besetzt) {
            wait();
        }
        System.out.println(id + " hat den Raum betreten.");
        return (besetzt = true);
    }

    public synchronized boolean verlassen(int id) {
        if (besetzt) {
            System.out.println(id + " hat den Raum verlassen.");
            besetzt = false;
            notifyAll();
            return true;
        }
        System.out.println("Something went wrong. :(");
        notifyAll();
        return false;
    }
}```


run:
Thread[Thread-0,5,main] hat sich registriert (und wartet).
Thread[Thread-11,5,main] hat sich registriert (und wartet).
Thread[Thread-10,5,main] hat sich registriert (und wartet).
Thread[Thread-8,5,main] hat sich registriert (und wartet).
Thread[Thread-9,5,main] hat sich registriert (und wartet).
Thread[Thread-5,5,main] hat sich registriert (und wartet).
Thread[Thread-7,5,main] hat sich registriert (und wartet).
Thread[Thread-6,5,main] hat sich registriert (und wartet).
Thread[Thread-2,5,main] hat sich registriert (und wartet).
Thread[Thread-4,5,main] hat sich registriert (und wartet).
Thread[Thread-3,5,main] hat sich registriert (und wartet).
Thread[Thread-1,5,main] hat sich registriert (und wartet).
-488510062 möchte Raum betreten und wartet.
-488510062 hat den Raum betreten.
-1015717788 möchte Raum betreten und wartet.
-1693518534 möchte Raum betreten und wartet.
1588632151 möchte Raum betreten und wartet.
-2133419254 möchte Raum betreten und wartet.
749199559 möchte Raum betreten und wartet.
422793031 möchte Raum betreten und wartet.
101532789 möchte Raum betreten und wartet.
1167190268 möchte Raum betreten und wartet.
686505792 möchte Raum betreten und wartet.
-446444601 möchte Raum betreten und wartet.
-2077086136 möchte Raum betreten und wartet.
-488510062 hat den Raum verlassen.
-2077086136 hat den Raum betreten.
-2077086136 hat den Raum verlassen.
-1015717788 hat den Raum betreten.
Luca / Luka-2077086136 wurde behandelt.
Leon-488510062 wurde behandelt.
-1015717788 hat den Raum verlassen.
-446444601 hat den Raum betreten.
Maximilian-1015717788 wurde behandelt.
-446444601 hat den Raum verlassen.
-1693518534 hat den Raum betreten.
-1693518534 hat den Raum verlassen.
686505792 hat den Raum betreten.
Luis / Louis-446444601 wurde behandelt.
Felix-1693518534 wurde behandelt.
686505792 hat den Raum verlassen.
1588632151 hat den Raum betreten.
1588632151 hat den Raum verlassen.
1167190268 hat den Raum betreten.
Tim686505792 wurde behandelt.
1167190268 hat den Raum verlassen.
-2133419254 hat den Raum betreten.
Jonas1588632151 wurde behandelt.
-2133419254 hat den Raum verlassen.
101532789 hat den Raum betreten.
Paul1167190268 wurde behandelt.
101532789 hat den Raum verlassen.
749199559 hat den Raum betreten.
-2133419254 wurde behandelt.
Lukas / Lucas101532789 wurde behandelt.
749199559 hat den Raum verlassen.
422793031 hat den Raum betreten.
Ben749199559 wurde behandelt.
422793031 hat den Raum verlassen.
Finn / Fynn422793031 wurde behandelt.
BUILD SUCCESSFUL (total time: 1 minute ?? seconds)



1. Debug- Ausgaben lassen den Code nicht schlank aussehen,
2. toString() überschrieben,
3. Raum muss sich die IDs merken,
4. Raum muss sicherstellen, dass bei (registrieren,) betreten, verlassen nicht irgendwer sich Zugang.

Das wär's hoffentlich erstmal. Grüße.

Edit: Wenn ich das vorweggenommen habn sollte, so muss das wieder weg, es ist ja nicht Sinn der Aufgabe, sie zu lösen, sondern sie zu erklären.

Also bitte raus nehmen, und ich erkläre das dann im Detail, ohne Implementierung.

Ok, Slater?

erstes Posting unnötig, zweites Posting unnötig,
Gott/ Schicksal bewahre jeden vor deinen Erklärungen,
man man man