Synchronisation eines kleinen Museums

BodyLAB

Bekanntes Mitglied
Hallo zusammen,

ich hab eine kleine Aufgabe die wie folgt ausschaut:
Ein Museum ermöglicht Besuchern den Eingang durch den Osteingang und den Ausgang durch den Westausgang.
An- und Abreise werden dem Museumsleiter über das Drehkreuze am Ein- und Ausgang signalisiert.
Wenn das Museum geöffnet ist, signalisiert der Museumsdirektor dem Controller, dass das Museum geöffnet ist, und
der Controller öffnet dann die Ankünfte und Abreisen.
Zum Zeitpunkt der Schließung signalisiert der Direktor, dass das Museum geschlossen ist.
Jetzt lässt der Lotse nur noch Abfahrten zu.


Öffnung um 9:00 Uhr und Schließung um 16:00 Uhr.
Aufgrund der aktuellen Pandemie-Situation achten Sie darauf, dass nur 50 Besucher gleichzeitig das Museum betreten dürfen.

Das Problem versuche ich gerade zu Lösen, nur habe ich ein Problem und weiß nicht ob es vielleicht an der Gepufferten Ausgabe liegt oder ob mein Programmcode ganz einfach misst ist.

Insgesamt habe ich derzeit 4 Klassen. Es fehlen noch ein paar Sachen aus der Übung die noch implementiert werden müssten, das Grundgerüst sieht so aus:
Java:
public class Eingang extends Thread {
    private Controller c;
    private int max = 50;

    public Eingang(Controller c) {
        this.c = c;
        this.start();
    }

    public void run() {
        while (c.museumOffen()) {
            if (c.getCount() < max)
                c.museumBetretten();
        }
    }
}

Java:
public class Ausgang extends Thread {
    private Controller c;

    public Ausgang(Controller c) {
        this.c = c;
        this.start();
    }

    public void run() {
        while (c.museumOffen()) {
                c.museumVerlassen();
        }
    }
}

Java:
public class Direktor extends Thread {
    private Controller c;

    public Direktor(Controller c) {
        this.c = c;
        this.start();
    }

    public void run() {
        try {
            c.museumWirdGeoeffnet();

            sleep(100);

            c.museumWirdGeschlossen();
        } catch (InterruptedException e) {
            e.getStackTrace();
        }

    }
}

Java:
public class Controller {
    private boolean offen;
    private int count;
    
    public synchronized void museumWirdGeoeffnet() {
        System.out.println("Der Direktor oeffnet das Museum");
        offen = true;
    }
    
    public synchronized boolean museumOffen() {
        return offen;
    }
    
    public synchronized void museumWirdGeschlossen() {
        System.out.println("Der Direktor schliesst das Museum");
        offen = false;
    }
    
    public synchronized int getCount() {
        return count;
    }
    
    public synchronized void museumBetretten() {
        while(count > 10) {
            try {
                wait();
            }catch(InterruptedException e) {
                e.getStackTrace();
            }
        }
        count++;
        System.out.println("Besucher " + count + " betritt das Museum");
    }
    
    public synchronized void museumVerlassen() {
        if(count > 0) {
            count--;
            System.out.println("Besucher " + count + " verlaesst das Museum");
        }
        notify();
    }   
    
    public static void main(String[] args) {
        Controller c = new Controller();
        Direktor d = new Direktor(c);
        Eingang e = new Eingang(c);
        Ausgang a = new Ausgang(c);
    }

}

In meiner Ausgabe gibt es Besucher die das Museum betreten obwohl es geschlossen wurde. Ist das mein verschulden oder liegt es am System.out.print?
Ausgabe schaut so aus:
Der Direktor oeffnet das Museum
Besucher 1 betritt das Museum
Besucher 2 betritt das Museum
Besucher 3 betritt das Museum
Besucher 4 betritt das Museum
Besucher 5 betritt das Museum
Besucher 6 betritt das Museum
Besucher 7 betritt das Museum
Besucher 8 betritt das Museum
Besucher 9 betritt das Museum
Besucher 10 betritt das Museum
Besucher 11 betritt das Museum
Besucher 10 verlaesst das Museum
Besucher 9 verlaesst das Museum
Besucher 8 verlaesst das Museum
Besucher 7 verlaesst das Museum
Besucher 6 verlaesst das Museum
Besucher 5 verlaesst das Museum
Besucher 4 verlaesst das Museum
Besucher 3 verlaesst das Museum
Besucher 2 verlaesst das Museum
Besucher 1 verlaesst das Museum
Besucher 0 verlaesst das Museum
Besucher 1 betritt das Museum
Besucher 2 betritt das Museum
Besucher 3 betritt das Museum
Besucher 4 betritt das Museum
Besucher 5 betritt das Museum
Besucher 6 betritt das Museum
Besucher 7 betritt das Museum
Besucher 8 betritt das Museum
Besucher 9 betritt das Museum
Besucher 10 betritt das Museum
Besucher 11 betritt das Museum
Besucher 10 verlaesst das Museum
Besucher 9 verlaesst das Museum
Besucher 8 verlaesst das Museum
Besucher 7 verlaesst das Museum
Besucher 6 verlaesst das Museum
Besucher 5 verlaesst das Museum
Besucher 4 verlaesst das Museum
Besucher 3 verlaesst das Museum
Besucher 2 verlaesst das Museum
Besucher 1 verlaesst das Museum
Besucher 0 verlaesst das Museum
Besucher 1 betritt das Museum
Besucher 2 betritt das Museum
Besucher 3 betritt das Museum
Besucher 4 betritt das Museum
Besucher 5 betritt das Museum
Besucher 6 betritt das Museum
Besucher 7 betritt das Museum
Besucher 8 betritt das Museum
Besucher 9 betritt das Museum
Besucher 10 betritt das Museum
Besucher 11 betritt das Museum
Besucher 10 verlaesst das Museum
Besucher 9 verlaesst das Museum
Besucher 8 verlaesst das Museum
Besucher 7 verlaesst das Museum
Besucher 6 verlaesst das Museum
Besucher 5 verlaesst das Museum
Besucher 4 verlaesst das Museum
Besucher 3 verlaesst das Museum
Besucher 2 verlaesst das Museum
Besucher 1 verlaesst das Museum
Besucher 0 verlaesst das Museum
Besucher 1 betritt das Museum
Besucher 2 betritt das Museum
Besucher 3 betritt das Museum
Besucher 4 betritt das Museum
Besucher 5 betritt das Museum
Besucher 6 betritt das Museum
Besucher 7 betritt das Museum
Besucher 8 betritt das Museum
Besucher 9 betritt das Museum
Besucher 10 betritt das Museum
Besucher 11 betritt das Museum
Besucher 10 verlaesst das Museum
Besucher 9 verlaesst das Museum
Besucher 8 verlaesst das Museum
Besucher 7 verlaesst das Museum
Besucher 6 verlaesst das Museum
Besucher 5 verlaesst das Museum
Besucher 4 verlaesst das Museum
Besucher 3 verlaesst das Museum
Besucher 2 verlaesst das Museum
Besucher 1 verlaesst das Museum
Besucher 0 verlaesst das Museum
Besucher 1 betritt das Museum
Besucher 2 betritt das Museum
Besucher 3 betritt das Museum
Besucher 4 betritt das Museum
Besucher 5 betritt das Museum
Besucher 6 betritt das Museum
Besucher 7 betritt das Museum
Besucher 8 betritt das Museum
Besucher 9 betritt das Museum
Besucher 10 betritt das Museum
Besucher 11 betritt das Museum
Besucher 10 verlaesst das Museum
Besucher 9 verlaesst das Museum
Besucher 8 verlaesst das Museum
Besucher 7 verlaesst das Museum
Besucher 6 verlaesst das Museum
Besucher 5 verlaesst das Museum
Besucher 4 verlaesst das Museum
Besucher 3 verlaesst das Museum
Besucher 2 verlaesst das Museum
Besucher 1 verlaesst das Museum
Besucher 0 verlaesst das Museum
Besucher 1 betritt das Museum
Besucher 2 betritt das Museum
Besucher 3 betritt das Museum
Besucher 4 betritt das Museum
Besucher 5 betritt das Museum
Besucher 6 betritt das Museum
Besucher 7 betritt das Museum
Besucher 8 betritt das Museum
Besucher 9 betritt das Museum
Besucher 10 betritt das Museum
Besucher 11 betritt das Museum
Besucher 10 verlaesst das Museum
Besucher 9 verlaesst das Museum
Besucher 8 verlaesst das Museum
Besucher 7 verlaesst das Museum
Besucher 6 verlaesst das Museum
Besucher 5 verlaesst das Museum
Besucher 4 verlaesst das Museum
Besucher 3 verlaesst das Museum
Besucher 2 verlaesst das Museum
Besucher 1 verlaesst das Museum
Besucher 0 verlaesst das Museum
Besucher 1 betritt das Museum
Besucher 2 betritt das Museum
Besucher 3 betritt das Museum
Besucher 4 betritt das Museum
Besucher 5 betritt das Museum
Besucher 6 betritt das Museum
Besucher 7 betritt das Museum
Besucher 8 betritt das Museum
Besucher 9 betritt das Museum
Besucher 10 betritt das Museum
Besucher 11 betritt das Museum
Besucher 10 verlaesst das Museum
Besucher 9 verlaesst das Museum
Besucher 8 verlaesst das Museum
Besucher 7 verlaesst das Museum
Besucher 6 verlaesst das Museum
Besucher 5 verlaesst das Museum
Besucher 4 verlaesst das Museum
Besucher 3 verlaesst das Museum
Besucher 2 verlaesst das Museum
Besucher 1 verlaesst das Museum
Besucher 0 verlaesst das Museum
Besucher 1 betritt das Museum
Besucher 2 betritt das Museum
Besucher 3 betritt das Museum
Besucher 4 betritt das Museum
Besucher 5 betritt das Museum
Besucher 6 betritt das Museum
Besucher 7 betritt das Museum
Besucher 8 betritt das Museum
Besucher 9 betritt das Museum
Besucher 10 betritt das Museum
Besucher 11 betritt das Museum
Besucher 10 verlaesst das Museum
Besucher 9 verlaesst das Museum
Besucher 8 verlaesst das Museum
Besucher 7 verlaesst das Museum
Besucher 6 verlaesst das Museum
Besucher 5 verlaesst das Museum
Besucher 4 verlaesst das Museum
Besucher 3 verlaesst das Museum
Besucher 2 verlaesst das Museum
Besucher 1 verlaesst das Museum
Besucher 0 verlaesst das Museum
Besucher 1 betritt das Museum
Besucher 2 betritt das Museum
Besucher 3 betritt das Museum
Besucher 4 betritt das Museum
Besucher 5 betritt das Museum
Besucher 6 betritt das Museum
Besucher 7 betritt das Museum
Besucher 8 betritt das Museum
Besucher 9 betritt das Museum
Besucher 10 betritt das Museum
Besucher 11 betritt das Museum
Besucher 10 verlaesst das Museum
Besucher 9 verlaesst das Museum
Besucher 8 verlaesst das Museum
Besucher 7 verlaesst das Museum
Besucher 6 verlaesst das Museum
Besucher 5 verlaesst das Museum
Besucher 4 verlaesst das Museum
Besucher 3 verlaesst das Museum
Besucher 2 verlaesst das Museum
Besucher 1 verlaesst das Museum
Besucher 0 verlaesst das Museum
Besucher 1 betritt das Museum
Besucher 2 betritt das Museum
Besucher 3 betritt das Museum
Besucher 4 betritt das Museum
Besucher 5 betritt das Museum
Besucher 6 betritt das Museum
Besucher 7 betritt das Museum
Besucher 8 betritt das Museum
Besucher 9 betritt das Museum
Besucher 10 betritt das Museum
Besucher 11 betritt das Museum
Besucher 10 verlaesst das Museum
Besucher 9 verlaesst das Museum
Besucher 8 verlaesst das Museum
Besucher 7 verlaesst das Museum
Besucher 6 verlaesst das Museum
Besucher 5 verlaesst das Museum
Besucher 4 verlaesst das Museum
Besucher 3 verlaesst das Museum
Besucher 2 verlaesst das Museum
Besucher 1 verlaesst das Museum
Besucher 0 verlaesst das Museum
Besucher 1 betritt das Museum
Besucher 2 betritt das Museum
Besucher 3 betritt das Museum
Besucher 4 betritt das Museum
Besucher 5 betritt das Museum
Besucher 6 betritt das Museum
Besucher 7 betritt das Museum
Besucher 8 betritt das Museum
Besucher 9 betritt das Museum
Besucher 10 betritt das Museum
Besucher 11 betritt das Museum
Besucher 10 verlaesst das Museum
Besucher 9 verlaesst das Museum
Besucher 8 verlaesst das Museum
Besucher 7 verlaesst das Museum
Besucher 6 verlaesst das Museum
Besucher 5 verlaesst das Museum
Besucher 4 verlaesst das Museum
Besucher 3 verlaesst das Museum
Besucher 2 verlaesst das Museum
Besucher 1 verlaesst das Museum
Besucher 0 verlaesst das Museum
Besucher 1 betritt das Museum
Besucher 2 betritt das Museum
Besucher 3 betritt das Museum
Besucher 4 betritt das Museum
Besucher 5 betritt das Museum
Besucher 6 betritt das Museum
Besucher 5 verlaesst das Museum
Besucher 4 verlaesst das Museum
Besucher 3 verlaesst das Museum
Besucher 2 verlaesst das Museum
Besucher 1 verlaesst das Museum
Besucher 0 verlaesst das Museum
Besucher 1 betritt das Museum
Besucher 2 betritt das Museum
Besucher 3 betritt das Museum
Besucher 4 betritt das Museum
Besucher 5 betritt das Museum
Besucher 6 betritt das Museum
Besucher 7 betritt das Museum
Besucher 8 betritt das Museum
Besucher 9 betritt das Museum
Besucher 10 betritt das Museum
Besucher 11 betritt das Museum
Besucher 10 verlaesst das Museum
Besucher 9 verlaesst das Museum
Besucher 8 verlaesst das Museum
Besucher 7 verlaesst das Museum
Besucher 6 verlaesst das Museum
Besucher 5 verlaesst das Museum
Besucher 4 verlaesst das Museum
Besucher 3 verlaesst das Museum
Besucher 2 verlaesst das Museum
Besucher 1 verlaesst das Museum
Besucher 0 verlaesst das Museum
Der Direktor schliesst das Museum
Besucher 1 betritt das Museum
 

Oneixee5

Top Contributor
Die Methode museumBetretten prüft nicht ob das Museum offen ist, somit ist es möglich das geschlossene Museum zu betreten.
 

Oneixee5

Top Contributor
In der Klasse Eingang schickst du 50 Besucher in das Museum. Das entspricht aber nicht der Aufgabe. Es können auch 1000 Besucher am Tag kommen - aber eben nur 50 Besucher gleichzeitig das Museum betreten. Du limitierst die Besucherzahl aber auf 11, wenn ich das richtig lese.
 

Oneixee5

Top Contributor
Es ist nicht üblich eine Klasse von Thread abzuleiten. Normalerweise implementiert man Runnable und verwendet den entsprechenden Konstruktor der Klasse Thread. Programmierung sollte immer gegen Interfaces erfolgen, wenn das irgendwie möglich ist.
Der Name 'c' ist kein geeigneter Variablenname und macht den Code unleserlich.
 

BodyLAB

Bekanntes Mitglied
Danke für die schnelle Antwort.
Einige Probleme habe ich jetzt noch.

Zum einen weiß ich nicht so recht wie ich das hin bekomme das es ein kommen und gehen von Threads ist. Sprich so das dort steht
Besucher 14 betritt das Museum
Besucher 6 verlaesst das Museum
Besucher 17 betritt das Museum
Besucher 7 betritt das Museum
Besucher 14 verlaesst das Museum

Glaube aber dann müsste ich das ganze komplett umbauen (verkomplizieren :D) oder?

Dann versuche ich die ganze Zeit das mehr Leute das Museum besuchen können ohne das mehr als 50 Besucher sich im Museum befinden doch das klappt nicht.

Wie beim Eingang habe ich beim Ausgang auch noch das Problem mit der Ausgabe. Es kommt vor das Besucher im Museum eingesperrt werden und das welche noch das Museum verlassen nachdem es geschlossen wurde.
In der Aufgabenstellung steht nicht genau drin wie man das umsetzten soll. Ich würde nun simpel wie ich bin :D In der Direktor Klasse eine Methode im Monitor aufrufen c.besucherRausKehren(). Diese ruft dann museumVerlassen auf. Nur weiß ich nicht ob das erlaubt wäre :D

Ist es normal das man sich mit Parallelität so schwer tut? Ich beschäftige mich jetzt schon seit gut 3 Monaten damit (gut ich war 6 Wochen Krank) doch habe das Gefühl als hätte ich nichts gelernt :-(

Normalerweise implementiert man Runnable und verwendet den entsprechenden Konstruktor der Klasse Thread. Programmierung sollte immer gegen Interfaces erfolgen, wenn das irgendwie möglich ist.
Das wusste ich noch überhaupt nicht. Werde das ändern. Brauch dann im Konstruktor nur new Thread(runnable).start() aufrufen :)
 

httpdigest

Top Contributor

Oneixee5

Top Contributor
Also ich denke dein Museum muss etwas wie eine Liste/Stack/Array von Besuchern enthalten. dieser darf nicht größer sein als 50. Wenn in dem Stack Besucher enthalten sind, dann müssen diese nach einer gewissen Zeit entfernt werden. Ich denke das Museum ist eine Klasse für welche ein Thread erforderlich ist. Jeder Besucher muss einen Zeitstempel enthalten, wann das Museum betreten wurde. Wenn der Besucher eine gewisse Anwesenheitszeit überschritten hat, dann wird er rausgeschickt.
Dann fehlt also noch die Logik, welche verhindert, dass das Museum überfüllt wird. Das hast du ja schon Ansatzweise umgesetzt.
 

BodyLAB

Bekanntes Mitglied
3 Monate ist gar nichts. Eher 3 Jahre.
Du lernst schon viel, aber du merkst ja auch, dass es immer noch viel mehr zu lernen gibt.
Das macht etwas Mut :)

Du kannst dir mal Deadlock Empire ansehen um sicher zu gehen dass du die Grundlagen mal verstanden hast.
Werde ich mir mal anschauen ;-) Doch ich bin mir sicher das dort vieles ist was ich noch nicht so genau verstehe :-(
Hab leider zu dem Thema auch nur zwei Deutsche Bücher hier liegen! Und da hab ich auch öfters mal ein Fragezeichen im Kopf.

Also ich denke dein Museum muss etwas wie eine Liste/Stack/Array von Besuchern enthalten. dieser darf nicht größer sein als 50. Wenn in dem Stack Besucher enthalten sind, dann müssen diese nach einer gewissen Zeit entfernt werden. Ich denke das Museum ist eine Klasse für welche ein Thread erforderlich ist. Jeder Besucher muss einen Zeitstempel enthalten, wann das Museum betreten wurde. Wenn der Besucher eine gewisse Anwesenheitszeit überschritten hat, dann wird er rausgeschickt.
Dann fehlt also noch die Logik, welche verhindert, dass das Museum überfüllt wird. Das hast du ja schon Ansatzweise umgesetzt.
Das werde ich gleich mal Probieren. Erst einmal habe ich jetzt alles verbessert doch leider auch immer noch einen Fehler (gerne auch mehr).
Wenn ich das if (c.getCount() < max) aus dem Eingang nehme, gibt es wieder Leute die rein gehen können obwohl zu ist :-( Somit stehen vor dem Eingang wohl immer nur 50 Leute was etwas doof ist :-( Hätte es auch lieber so das wenn um 9 Uhr 1000 Leute vor dem Eingang stehen aber nur 50 rein dürfen wieder 100 nach kommen könnten und dann eben 1050 vor der Tür stehen etc. ;-)

Hier jetzt mal meine neue Version:
Java:
public class Controller {
    private boolean offen, rausKehren;
    private int count;

    public synchronized void museumWirdGeoeffnet() {
        System.out.println("Der Direktor oeffnet das Museum");
        offen = true;
    }
    
    public synchronized boolean getRausKehren() {
        return rausKehren;
    }

    public synchronized boolean museumOffen() {
        return offen;
    }

    public synchronized void museumWirdGeschlossen() {
        while(count > 0) {
            try {
                wait();
            }catch(InterruptedException e) {
                e.getStackTrace();
            }
        }
        rausKehren = false;
        System.out.println("Der Direktor schliesst das Museum");
    }

    public synchronized int getCount() {
        return count;
    }

    public synchronized void museumBetretten() {
        if (offen) {
            while (count > 50) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.getStackTrace();
                }
            }
            count++;
            System.out.println("Besucher " + count + " betritt das Museum");
        }
    }

    public synchronized void museumVerlassen() {
        if (count > 0) {
            System.out.println("Besucher " + count + " verlaesst das Museum");
            count--;
        }

        notify();
    }
    
    public synchronized void rausKehren() {
        offen = false;
        rausKehren = true;
        notify();
    }

    public static void main(String[] args) {
        Controller c = new Controller();
        Direktor d = new Direktor(c);
        Eingang e = new Eingang(c);
        Ausgang a = new Ausgang(c);
    }

}

public class Ausgang implements Runnable {
    private Controller c;

    public Ausgang(Controller c) {
        this.c = c;
        new Thread(this).start();
    }

    public void run() {
        while (c.museumOffen() || c.getRausKehren()) {
                c.museumVerlassen();
        }
    }
}

public class Eingang implements Runnable {
    private Controller c;
    private int max = 50;

    public Eingang(Controller c) {
        this.c = c;
        new Thread(this).start();
    }

    public void run() {
        while (c.museumOffen()) {
            if (c.getCount() < max)
                c.museumBetretten();
        }
    }
}

public class Direktor implements Runnable {
    private Controller c;

    public Direktor(Controller c) {
        this.c = c;
        new Thread(this).start();
    }

    public void run() {
        try {
            c.museumWirdGeoeffnet();

            Thread.sleep(10);

            c.rausKehren();

            c.museumWirdGeschlossen();
        } catch (InterruptedException e) {
            e.getStackTrace();
        }

    }
}
 

Jw456

Top Contributor
wieso muss der Thread warten, wenn mehr als 50 User drin sind?

Wo wie wird der Thread wider aufgeweckt?
Wenn mehr als 50 drin sind ist halt kein Einlas mehr möglich. Erst wider wenn count kleiner als 50.
 
Zuletzt bearbeitet:

BodyLAB

Bekanntes Mitglied
wieso muss der Thread warten, wenn mehr als 50 User drin sind?

Wo wie wird der Thread wider aufgeweckt?
Wenn mehr als 50 drin sind ist halt kein Einlas mehr möglich. Erst wider wenn count kleiner als 50.
Ja genau das ist meine Frage.

Ich mach das aus Eingang raus und versuche im Controller das ganze zu synchronisieren doch das klappt nicht.
 

Jw456

Top Contributor
beim Verlassen prüfst du den Counter beim Kommen nicht.


Baue doch mal zum testen eine WarteZeit in die run Methoden von Kommen und Verlassen ein damit du es besser beobachten kannst , und mache die Zeit vom Direktor auch länger.

Mache auch einer Textausgabe wenn das Warten im Controller ausgelöst wird und schaue wenn das Warten aufgehoben wird.
 
Zuletzt bearbeitet:

BodyLAB

Bekanntes Mitglied
Interessant wenn ich sleep in Eingang und Ausgang mache, habe ich folgende Ausgabe:
Besucher 51 verlaesst das Museum
Besucher 51 betritt das Museum
Besucher 51 verlaesst das Museum
Besucher 51 betritt das Museum
Besucher 51 verlaesst das Museum
Besucher 51 betritt das Museum
Besucher 51 verlaesst das Museum
Besucher 51 betritt das Museum
Besucher 51 verlaesst das Museum
verstehen tue ich es nur leider überhaupt nicht gerade. Glaube ich schaue morgen nochmal drüber.
Möchte morgen auch noch versuchen das ganze dann mit Besuchern hin zu bekommen :)
 

Jw456

Top Contributor
Du hast ja drei versiedende Threads . Überlege welchen Thread du in welcher Methode zum warten schickst und wo du ihn wider aufweckst.

Tipp zum wider aufwecken mit notify brauchst du die Instanz der Threads den du wecken willst. Du kannst den Thread nur aus einem anderen wider starten. Nicht in sich selber.
 

BodyLAB

Bekanntes Mitglied
Du hast ja drei versiedende Threads . Überlege welchen Thread du in welcher Methode zum warten schickst und wo du ihn wider aufweckst.

Tipp zum wider aufwecken mit notify brauchst du die Instanz der Threads den du wecken willst. Du kannst den Thread nur aus einem anderen wider starten. Nicht in sich selber.
Achso. Du meinst also ich soll den Eingang Thread schlafen legen sobald 50 Leute drin sind. Sobald wieder Leute raus gehen, weckt der Ausgang Thread den Eingang Thread so ungefähr oder?
 

Jw456

Top Contributor
Achso. Du meinst also ich soll den Eingang Thread schlafen legen sobald 50 Leute drin sind. Sobald wieder Leute raus gehen, weckt der Ausgang Thread den Eingang Thread so ungefähr oder?
nein einfach den Counter nicht mehr hoch zählen keinen mehr rein lassen. wenn einer raus geht kommt beim nächsten schleifen durchlauf wider einer rein.
 

Jw456

Top Contributor
Besucher 51 verlaesst das Museum
Besucher 51 betritt das Museum
Besucher 51 verlaesst das Museum
Besucher 51 betritt das Museum
Besucher 51 verlaesst das Museum
Besucher 51 betritt das Museum
Besucher 51 verlaesst das Museum
Besucher 51 betritt das Museum
einer geht einer kommt so soll es doch sein.
 

Jw456

Top Contributor
So sottest du ein asynchrones Verhalten beobachten können.

Java:
public class Controller {
    private boolean offen, rausKehren;
    private int count;

    public synchronized void museumWirdGeoeffnet() {
        System.out.println("Der Direktor oeffnet das Museum");
        offen = true;
    }

    public synchronized boolean getRausKehren() {
        return rausKehren;
    }

    public synchronized boolean museumOffen() {
        return offen;
    }

    public synchronized void museumWirdGeschlossen() {
        while(count > 0) {
            try {
                System.out.println("schliessen Warten");
                wait();
            }catch(InterruptedException e) {
                e.getStackTrace();
            }
        }
        rausKehren = false;
        System.out.println("Der Direktor schliesst das Museum");
    }

    public synchronized int getCount() {
        return count;
    }

    public synchronized void museumBetretten() {
        if (offen) {
            /*while (count > 50) {
                try {
                    System.out.println("betretten  Warten");
                    wait();

                } catch (InterruptedException e) {
                    e.getStackTrace();
                }
            }*/
            if(count<=50) {
                count++;
                System.out.println("Besucher " + count + " betritt das Museum");
            }
        }
    }

    public synchronized void museumVerlassen() {
        if (count > 0) {
            System.out.println("Besucher " + count + " verlaesst das Museum");
            count--;
        }

        notify();
    }

    public synchronized void rausKehren() {
        offen = false;
        rausKehren = true;
        notify();
    }

    public static void main(String[] args) {
        Controller c = new Controller();
        Direktor d = new Direktor(c);
        Eingang e = new Eingang(c);
        Ausgang a = new Ausgang(c);
    }

}

public class Eingang implements Runnable {
    private Controller c;
    private int max = 50;

    public Eingang(Controller c) {
        this.c = c;
        new Thread(this).start();
    }

    public void run() {
        while (c.museumOffen()) {
            if (c.getCount() < max)
                c.museumBetretten();
            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}


public class Ausgang implements Runnable {
    private Controller c;

    public Ausgang(Controller c) {
        this.c = c;
        new Thread(this).start();
    }

    public void run() {
        while (c.museumOffen() || c.getRausKehren()) {
            try {
                Thread.sleep(3);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            c.museumVerlassen();
        }
    }
}


public class Direktor implements Runnable {
    private Controller c;

    public Direktor(Controller c) {
        this.c = c;
        new Thread(this).start();
    }

    public void run() {
        try {
            c.museumWirdGeoeffnet();

            Thread.sleep(500);

            c.rausKehren();

            c.museumWirdGeschlossen();
        } catch (InterruptedException e) {
            e.getStackTrace();
        }

    }
}
 

BodyLAB

Bekanntes Mitglied
🤗🤗🤗 Jipi so sieht es doch super aus. Danke für eure tolle Mitarbeit und die super Hilfe :)

Eine Frage habe ich, gibt es eine Art "Grundregel" wann man while(...) oder if(...) in einem synchronized Block (Methode) nutzt?
Ich verstehe was da passiert doch alle Beispiele die ich sehe sind mit while(..). Dort muss dann der Thread wenn er ran kommt eben wieder Abfragen ob er überhaupt ran darf falls NEIN geht er eben wieder schlafen. Jetzt hätten wir aber ja if(..) somit fragt der Thread nur einmal. Mhhh... wenn Eingang z. B. aber dran ist, wissen wir ja das er zu ende laufen muss, selbst wenn ein Threadwechsel statt finden würde wäre Controller ja Blockiert durch synchronized. Damit wäre das while(...) überflüssig.

Kann man sagen das, wenn es eine Art Reihenfolge gibt ein if(..) ausreicht? Oder kann man das nie pauschal sagen?
 

Jw456

Top Contributor
while(...) ist eine Schleife die den Block solange widerholt wie der Ausdruck (Bedingung ) True ist.
if(...) bei If wird der Block nur einmal durchlaufen wenn die Bedingung True ist.

Das hat nichts mit synchronized Block zu tuen.

Bei syncronized kann halt immer nur ein Thread in die Methode rein die anderen müssen warten. Wer zuerst kommt mahlt zuerst der Rest muss warten.
 
Zuletzt bearbeitet:

BodyLAB

Bekanntes Mitglied
while(...) ist eine Schleife die den Block solange widerholt wie der Ausdruck (Bedingung ) True ist.
if(...) bei If wird der Block nur einmal durchlaufen wenn die Bedingung True ist.
Das ist mir ja geläufig 😇
Nur habe ich eben bis jetzt nur while(..) gesehen und dachte das müsste man so immer machen.

Dann liegt es wohl an der Aufgabenstellung das man es so machen muss. Mensch ich tu mir hier so schwer als würde ich von Null anfangen zu Programmieren :-( Sry auch für die "doofen" Fragen dann meiner Seits :-D
 

KonradN

Super-Moderator
Mitarbeiter
Also ich habe ehrlich gesagt meine Probleme, Deine Implementation zu verstehen. Ich sehe keine Besucher. Was ist dieses Eingang für ein Thread? Also extrem dubios.

Was hier helfen würde, wäre eine genaue Beschreibung, was das für Elemente vorkommen und was diese machen.

Ist der Text der Aufgabe so komplett? Dann findet man da so diverse Aktöre:
  • Besucher - es gibt mehrere Besucher, die das Museum besuchen wollen.
  • Es gibt einen Museumsleiter, der irgendwas was macht oder dem etwas signalisiert wird.
  • u.s.w.

Und da habe ich dann doch ein paar Probleme, das wieder zu finden bei Dir und an Deinem Code kann ich das alles auch nicht wirklich ablesen.

Vielleicht hast Du ja mehr Informationen, als das, was Du uns gegeben hast, so dass Dein Ansatz Sinn ergibt.

Ich selbst hätte jetzt sowas gemacht wie:
jeder Besucher ist ein Thread. Dieser will das Museum besuchen und schaut daher:
  • Ist das Museum offen? Wenn nicht, dann hat sich das mit dem Besuch erledigt.
  • Dann betritt er das Museum. Wenn das Museum gerade voll ist, dann muss er warten.
  • Wenn er das Museum betreten hat, dann kann er das genießen. Das könnte dann auch wieder eine Art Warten sein.
  • Wenn er es genug besucht hast, dann verlässt er das Museum wieder
  • Und ganz wichtig: Es kann ihm gesagt werden: Das Museum schließt, gehen sie bitte. Dann würde das "warten" auch abgebrochen werden!

Du hast dann ein Museum / Controller / was auch immer. Das sorgt halt dafür, dass nie zu viele Besucher im Museum sind und so.

Du hast einen Museumsdirektor, der halt das Museum öffnet und dann später wieder schließt.

Die Besucher müssen generiert werden. Du kannst also einen Thread erstellen, der ständig Besucher-Threads erzeugt und startet.

Das wäre dann ggf. ein Vorgehen wie:
  • Museum wird erstellt, ist geschlossen.
  • Der Thread für die Besucher wird gestartet, dieser erzeugt jede 1/10 Sekunde einen Besucher. Diese bekommen dann eine Nummer.
  • Der Direktor wird gestartet, nach 5 Sekunden öffnet er das Museum, nach 30 Sekunden schließt er das Museum.

Mit den Besuchern passiert dann folgendes:
  • Die Besucher wollen dann das Museum besuchen, Museum ist geschlossen -> "Besucher 1: Museum geschlossen!"
  • irgendwann ist das Museum dann offen. Dann kommt etwas wie: "Besucher 50: Museum offen - betreten"
  • So die Besucher noch nicht das Museum verlassen haben, kommt dann irgendwann "Besucher: 100: Museum offen - in Warteschlange!"
  • Dann verlässt Besucher 50 das Museum ggf. wieder: "Besucher 50: Museum verlassen." so dass dann ein Besucher rein kann: "Besucher 100: Museum betreten."
  • ...

Das wäre dann etwas, das ich nachvollziehen kann und das ich da etwas erwarten würde. Aber wie gesagt: Dir liegen evtl. schlicht mehr Informationen vor und daher ist da tatsächlich etwas anderes zu bauen wie Du es da in Ansätzen hast. Aber irgendwie erscheint mir das gerade nicht wirklich alles so sinnbehaftet.
 

BodyLAB

Bekanntes Mitglied
@KonradN GENAU DAS SELBE PROBLEM HATTE ICH GANZ ZU ANFANG VON DIESER AUFGABE!
Denn so wie du es beschreibst hätte ich es auch verstanden. Das ganze habe ich dann so unserem Tutor erklärt und er/sie meinte dann NÖ das ist viel viel zu weit gedacht. Nur so wie es da steht machen.

Den Ansatz mit den Besuchern hatte ich damals auch versucht zu implementieren und bin leider komplett gescheitert weil es viel zu komplex auf einmal wurde. Vielleicht bin ich aber wirklich dafür einfach zu "doof" oder denke um 1000 Ecken :-( so genau weiß ich das momentan noch nicht.

Nur läuft mir gerade auch etwas die Zeit davon um solche Aufgaben so ausführlich machen zu können. Deswegen, hört es sich jetzt nicht so gut an doch denke ich würde ich es hierbei belassen.

Vielleicht finde ich ja noch Zeit und werde dann deine tollen Ideen einarbeiten und daraus ein ebenfalls für mich sinnvolleres Programm bauen :)
Doch es gibt noch einiges was ich erledigen muss und ebenfalls stelle ich gerade fest überhaupt noch nicht verstanden habe. Selbst so Themen wie Petri-Netze oder bankier algorithmus fallen mir gerade nicht leicht. Es fehlt einfach die Übung. Vielleicht unterstützt ihr mich bei solchen Fragen ja ebenfalls :)

____
Was auch echt nett wäre bei diesem Museums Programm wäre eine mini GUI :) Man baut einfach ein Haus und die Besucher z. B. als StrichMenschen. Diese wandern dann in das Haus (Museum) sind 50 drin kommt keiner mehr rein und anders laufen sie hinten eben wieder raus :-D Wäre ebenfalls eine Idee wie ich das später gerne mal versuchen würde.
 

Jw456

Top Contributor
Du hast ja die Theresas nur um das Drehkreuz am Eingang und Ausgang zu Simulieren.

Bei jeden Schleifen durchlauf der Threads dreht sich sozusagen das Kreutz.

Ps Wie wäre es wenn du die Aufgabe mal im Original zeigst.
 

BodyLAB

Bekanntes Mitglied
Die Aufgabe:
A museum allows visitors to enter through the east entrance and exit through the
west exit. Arrival and departure are signaled to the museum manager through the
turnstiles at the entrance and exit. When the museum is open, the museum director
signals to the controller that the museum is open, and the controller then allows both
arrivals and departures. At the time of closure, the director signals that the museum
is closed. Now, the controller only allows departures.
There are at least four processes / monitors in this exercise: East, West, Control and
Director. Identify which of these should be threads and which should be monitors.
Provide a Java implementation of all classes and simulate a day in the museum
opening at 9:00 a.m. and closing at 4:00 p.m. Due to the current pandemic situation
take care that only 50 visitors may simultaneously enter the museum.
 

Jw456

Top Contributor
Ein Thread für Eingang und Ausgang zum Simulieren ist meiner Meinung richtig.

Ob es einen für den Direktor braucht fragwürdig nicht unbedingt.



Was du nicht hast ist eine Signalisierung das das Museum voll ist. Auch keine direkte sperre, für das Eingangs Kreutz. Also für den Thread, der das Kreutz darstellt. Das warten sollte eigentlich im dem Thread sein der ja den Besucher Strom simuliert.
 

KonradN

Super-Moderator
Mitarbeiter
Die englische Beschreibung ist ja auch eindeutig:
There are at least four processes / monitors in this exercise: East, West, Control and
Director

Und die Aufgabe hat ja auch schon einen ersten Schritt genannt:
Identify which of these should be threads and which should be monitors.

Ich würde halt generell dazu raten, immer erst als erstes genau zu formulieren, was denn die Aufgabe dann genau umfasst. Das ist immer ein wichtiger Schritt vor dem Start der Implementation.

East / West sind ja Eingang und Ausgang und Threads. Das wäre also schon beantwortet. Und wenn man sich den letzten Code von @Jw456 anschaut, dann hat man das auch für die beiden anderen Elemente beantwortet.

Dann bleibt nur noch die Frage, was denn diese Klasse genau machen sollen bzw. was die für eine Funktionalität haben sollen. Was soll genau passieren? Kannst Du das einmal im Detail beschreiben? Wenn das gewünschte Verhalten klar ist, dann kann man schauen, was notwendig ist, wenn man das jeweils implementiert. Dann wird auch klar, wo ggf. eine Schleife sein muss und wo eben keine Schleife sein darf.
 

BodyLAB

Bekanntes Mitglied
:rolleyes: oh weh ja da habe ich wohl euch nicht richtig erklärt was ich vor habe.

Also wie jetzt schon geschrieben wurde ist mein Eingang und Ausgang => East und West
Diese habe ich als Threads identifiziert, da sie die Besucher simulieren sollen die ja rein und raus aus dem Musem gehen können.

Der Direktor ist eigentlich nur aus Spaß ein Thread. Diesen könnte man auch als normale Klasse machen und dann eine Methode aufrufen die dann die Methoden im Controller aufruft und die Simulation beginnt.

Der Controller ist mein Monitor, dieser soll die Synchronisation der Threads sicherstellen so das es zu keinen inkonsistenzen kommt.

Das signalisieren dass das Museum zu ist fehlt oh ja. Könnte ich das alles nicht in der Methode betretteMuseum() erledigen. Diese habe ich nun so abgeändert.


Java:
public synchronized void museumBetretten() {
        if (offen) {
            if(count<50) {
                count++;
                System.out.println("Besucher " + count + " betritt das Museum");
            }
            else {
                System.out.println("Das Museum ist voll");
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

Somit würde signalisiert werden das unser Museum jetzt voll ist. Dann legt sich wenn ich alles richtig verstehe, der Eingang schlafen. Irgendwann kommt der Ausgang wieder dran und ein Besucher verlässt das Museum. Diese Methode ruft notify() auf und weckt somit den Eingang Thread. Hab ja nur zwei Threads in der hin sich :)

Macht das Sinn? Ist es jetzt etwas besser erklärt?
 

Jw456

Top Contributor
nur weil count nicht kleiner als 50 ist muss es nicht voll sein, können ja auch esrst 10 im Museum sein.

grösser gleich als 50 würde sinn machen um anzuzeigen das es voll ist
 

KonradN

Super-Moderator
Mitarbeiter
Also wie jetzt schon geschrieben wurde ist mein Eingang und Ausgang => East und West
Diese habe ich als Threads identifiziert, da sie die Besucher simulieren sollen die ja rein und raus aus dem Musem gehen können.

Der Direktor ist eigentlich nur aus Spaß ein Thread. Diesen könnte man auch als normale Klasse machen und dann eine Methode aufrufen die dann die Methoden im Controller aufruft und die Simulation beginnt.
Wer sollte denn diese Methode vom Direktor aufrufen? Der Direktor muss also ein Thread sein.

Bei allen Deinen Ansätzen fehlt mir schlicht das Verständnis, was da überhaupt passieren soll. Ich kann bei deinen Code-Ansätzen nicht ablesen, was Du denn da genau machen willst.

Ein Besucher will in das Museum. Was kann dann passieren und wie reagiert man? Du musst das erst einmal in Worten beschreiben! Dann kann man das implementieren. Nur am Code rumbasteln ohne das, was passieren soll zu verstehen, wird nicht zum Ziel führen.
 

BodyLAB

Bekanntes Mitglied
nur weil count nicht kleiner als 50 ist muss es nicht voll sein, können ja auch esrst 10 im Museum sein.
Okay, nur so ganz verstehen tu ich es nicht. Jetzt hab ich einfach ein else if(count >= 50) eingebaut. Doch was bringt mir das jetzt? Mehr Lesbarkeit?

@KonradN ich kann es leider nicht besser. Dachte mir was passiert als erstes? Naja der Direktor kommt und sagt so jetzt wird das Museum geöffnet. Das passiert dann über den Methodenaufruf c.museumWirdGeoeffnet(). Nun läuft unser Direktor munter durchs Museum (gedanklich) oder ruht sich irgendwo aus (keine Ahnung was so ein Museum Direktor alles erledigen muss). Nach einer gewissen Zeit gibt er bescheid, dass alle Leute raus müssen da unser Museum geschlossen wird. Dies erfolgt mit der Methode c.rausKehren(); Sobald alle Besucher draußen sind Sperrt er zu und geht nach Hause.

Sobald das Museum geöffnet wurde, bekommt der Eingang und Ausgang Bescheid. Im Eingang läuft dann bis das Museum geschlossen wird eine Methode c.museumBetretten(); Das heißt es dürfen Besucher durch das Drehkreuz (gedanklich) gehen um ins Museum zu gelangen. Es dürfen ja nicht mehr als 50 rein, somit wird nach 50 gesagt Stopp Museum ist voll.

Zugleich kann der Ausgang Thread an die Reihe kommen um Leute aus dem Museum zu schmeißen :D (also hier gehen eben gedanklich die Leute wieder raus) Soll das Museum geschlossen werden, werden vorher die restlichen Besucher rausgekehrt und dann das Museum geschlossen.

Ich kann es leider nicht besser. Bin ja froh das Ihr mir geholfen habt, das es derzeit überhaupt so schön läuft wie derzeit ;)
 

KonradN

Super-Moderator
Mitarbeiter
Natürlich kannst Du es auch besser - du verstehst nur noch nicht, was wir verlangen.

Du hast ein Museum und einen Thread Eingang, der Besucher in das Museum lässt.
Er ruft also eine Methode auf dem Museum auf, dass ein Besucher hinein will. Und wenn ein Besucher drin ist, dann ruft er es direkt wieder auf. Er packt also ständig Besucher in das Museum. Damit das erfolgreich funktioniert und die CPU nicht ausgelastet wird, muss der Thread sich immer, wenn nichts zu tun ist, schlafen legen.

Was kann es nun beim Museum für Fälle geben?
  • Es kann geschlossen sein. Was soll dann passieren?
  • Es kann geöffnet sein und es sind noch keine max Pesonen drin. Was dann?
  • Es kann geöffnet sein und es sind schon max Personen drin. Was dann?

Das musst musst Du jetzt spezifizieren - und zwar in Worten.
 

Jw456

Top Contributor
eigentlich brauchst du diese Begrenzung nicht das soll und tut ja dein Controller.
Der soll verbieten das weiter Besucher in das Museum können .
der soll anzeigen das voll ist der soll anzeigen das geschossen wurde ...

Das muss der simulierte Besucher Strom nicht machen.
Wird in Wirklichkeit auch nicht so sein. Die kommen und stellen sich an. Schauen auf die Anzeige. Museum offen, voll, der nächste bitte , Museum schließt bitte alle das Museum verlassen …

Java:
 while (c.museumOffen()) { // ist ok wenn Museum zu Thread wird beendet Besucher gehen wider nach Hause.
            if (c.getCount() < max) // nicht notwendig dein wait das sperren des Drehkreuz wird sonnst ja nicht ausgelöst.
                c.museumBetretten();
 
Zuletzt bearbeitet:

BodyLAB

Bekanntes Mitglied
  • Es kann geschlossen sein. Was soll dann passieren?
  • Es kann geöffnet sein und es sind noch keine max Pesonen drin. Was dann?
  • Es kann geöffnet sein und es sind schon max Personen drin. Was dann?
Ist das Museum noch geschlossen, dachte ich das die Besucher dann vor der Tür stehen. Andernfalls könnte der Eingang dann eben Schlafen bis es geöffnet wird.

Wenn es offen ist und noch keine max. Personen drin sind, können die Besucher das Museum betretten.

Wenn es offen ist und schon max. Personen drin sind, kann der Eingang sich schlafen legen und warten bis irgendwann jemand raus geht.

Meinst du so in etwas?

if (c.getCount() < max) // nicht notwendig dein wait das sperren des Drehkreuz wird sonnst ja nicht ausgelöst.
Ja das hatte ich vorher schon raus genommen :) Hier nur nicht gepostet das stimmt. Danke für den Hinweis ;-)
 

KonradN

Super-Moderator
Mitarbeiter
Andernfalls könnte der Eingang dann eben Schlafen bis es geöffnet wird.
Also kann dann der Thread sich schlafen legen -> Muss man dann im Hinterkopf behalten, denn beim Öffnen muss er dann geweckt werden!)

Meinst du so in etwas?
Ja genau. Das wäre dann der Ablauf, der in dem Controller umgesetzt werden muss.

Also hätten wir jetzt im Thread für den (einen) Eingang einfach nur ein
Java:
while (true) {
    museum.eintreten();
}

Und im eintreten hätte man dann ja an Logik:
  • Ist das Museum geschlossen? -> Schlafen legen!
  • Sonst: Ist das Museum bereits voll? -> Schlafen legen!
  • Sonst: Museum wird betreten.

Jetzt muss man noch überlegen, wo man die Schleife baut. Da würde aus meiner Sicht eine Schleife drum gehören, die verlassen wird, wenn man das Museum betreten hat.

Das wäre dann erst einmal der Code für das Eintreten (für jetzt!)



Jetzt musst Du Dir das beim Ausgang überlegen. Was passiert beim Ausgang? Was für Fälle gibt es da? Und was muss da gemacht werden?
 

BodyLAB

Bekanntes Mitglied
Okay :) Jetzt habe auch ich das verstanden.
Hab es mal umgesetzt. Auch beim Ausgang. Wäre ja doof wenn der Ausgang benutzt werden könnte wenn noch niemand da ist. Ist zwar nicht unbedingt notwendig doch es gibt mir ein besseres Gefühl :D

Java:
package Aufgabe1;

public class Controller {
    private boolean offen, rausKehren;
    private int count;

    public synchronized void museumWirdGeoeffnet() {
        System.out.println("Der Direktor oeffnet das Museum");
        offen = true;
        notifyAll();
    }

    public synchronized boolean getRausKehren() {
        return rausKehren;
    }

    public synchronized boolean museumOffen() {
        return offen;
    }

    public synchronized void museumWirdGeschlossen() {
        while (count > 0) {
            try {
                System.out.println("schliessen Warten");
                wait();
            } catch (InterruptedException e) {
                e.getStackTrace();
            }
        }
        rausKehren = false;
        System.out.println("Der Direktor schliesst das Museum");
    }

    public synchronized void museumBetretten() {
        if (offen) {
            if (count < 50) {
                count++;
                System.out.println("Besucher " + count + " betritt das Museum");
            } else if (count >= 50) {
                System.out.println("Das Museum ist voll");
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void museumVerlassen() {
        if (offen) {
            if (count > 0) {
                System.out.println("Besucher " + count + " verlaesst das Museum");
                count--;
            } else {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public synchronized void rausKehren() {
        offen = false;
        rausKehren = true;
        notifyAll();
    }

    public static void main(String[] args) {
        Controller c = new Controller();
        Direktor d = new Direktor(c);
        Eingang e = new Eingang(c);
        Ausgang a = new Ausgang(c);
    }

}

Was mich jetzt nur stört und vorher gar nicht aufgefallen ist, ist das es eine Reihenfolge gibt bzw. geben muss wie die Klassen aufgerufen werden müssen :-( Um das zu beheben würde mir aber nur einfallen das ich eine Art init-Methode im Controller hätte. Wir übergeben dem Controller den Direktor, Eingang und Ausgang. Diese init Methode sorgt dann dafür (oder auch der Konstruktor vom Controller) dass erst der Direktor los laufen darf und dann die anderen zwei :)
Was ich mich dabei jetzt aber wieder frage ist, was ist wenn viel Last auf einem System ist. Der Controller dann die Klassen initialisiert und der Direktor so gesehen gar nicht die run-Methode ausführen kann, ein Threadwechsel statt findet. Dann könnte z. B. der Eingang die run-Methode ausführen und beendet die while Schleife auf der Stelle da der Direktor das Museum nicht aufgemacht hat. 🤨 Das finde ich gerade echt Problematisch.
Werde es mal umbauen und schauen ob es dann noch läuft wie ich es mir vorstelle, löst nur das Problem nicht gänzlich oder?
 

BodyLAB

Bekanntes Mitglied
Also ich bekomme es leider nicht hin erst dann zu starten wenn Direktor wirklich gestartet ist.
Java:
Controller c = new Controller();
        Direktor d = new Direktor(c);
        //Hier pruefen ob Direktor run Ausführt
        Eingang e = new Eingang(c);
        Ausgang a = new Ausgang(c);

Code:
public class Direktor implements Runnable {
    private Controller c;
    private boolean running = false;

    public Direktor(Controller c) {
        this.c = c;
            new Thread(this).start();
    }

    public void run() {
        try {
            running = true;
            c.museumWirdGeoeffnet();

            Thread.sleep(500);

            c.rausKehren();

            c.museumWirdGeschlossen();
        } catch (InterruptedException e) {
            e.getStackTrace();
        } finally {
            running = false;
        }

    }

    public boolean isRunning() {
        return running;
    }
}

Ist es aber so gesehen dann nicht reiner Zufall das es läuft?
 

Jw456

Top Contributor
Dann starte doch die beiden entweder im Konstruktor oder im der run vom Direktor.

Wie schaust denn deine run, while Schleife in deinem Eingang und Ausgang jetzt aus?
 
Zuletzt bearbeitet:

Jw456

Top Contributor
Java:
 public synchronized void museumVerlassen() {
        if (offen) {
            if (count > 0) {
                System.out.println("Besucher " + count + " verlaesst das Museum");
                count--;
            } else {
                try {
                    wait(); // das müsste doch ein else vom ersten if sein also offen.
// du willst doch warten das Kreutz sperren wenn das Museum zu ist.

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
 

BodyLAB

Bekanntes Mitglied
Ich hab das mit dem wait() bei museumVerlassen ganz raus geworfen. Dann ging es nicht mehr, hatte endlosschleife. Ich mach wohl irgendwo ein notiryAll() falsch :-(

Hier jetzt nochmal alles. Ob es nun bis auf das mit dem mueseumVerlassen aber wirklich richtig läuft weiß ich nicht. Denn ich weiß nicht wie die JVM die Threads behandelt. Ich starte ja nun im Konstruktor alle Threads doch irgendwie habe ich das Gefühl das sich nichts geändert hat oder irre ich mich.

Java:
public class Controller {
    private boolean offen, rausKehren;
    private int count;

    public synchronized void museumWirdGeoeffnet() {
        System.out.println("Der Direktor oeffnet das Museum");
        offen = true;
        notifyAll();
    }

    public synchronized boolean getRausKehren() {
        return rausKehren;
    }

    public synchronized boolean museumOffen() {
        return offen;
    }

    public synchronized void museumWirdGeschlossen() {
        while (count > 0) {
            try {
                System.out.println("schliessen Warten");
                wait();
            } catch (InterruptedException e) {
                e.getStackTrace();
            }
        }
        rausKehren = false;
        System.out.println("Der Direktor schliesst das Museum");
    }

    public synchronized void museumBetretten() {
        if (offen) {
            if (count < 50) {
                count++;
                System.out.println("Besucher " + count + " betritt das Museum");
            } else if (count >= 50) {
                System.out.println("Das Museum ist voll");
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void museumVerlassen() {
        if (offen) {
            if (count > 0) {
                System.out.println("Besucher " + count + " verlaesst das Museum");
                count--;
            }
        }
    }

    public synchronized void rausKehren() {
        offen = false;
        rausKehren = true;
        notifyAll();
    }

    public static void main(String[] args) {
        Controller c = new Controller();
        Direktor d = new Direktor(c, new Eingang(c), new Ausgang(c));

    }
}

public class Direktor implements Runnable {
    private Controller c;
    private Eingang eingang;
    private Ausgang ausgang;

    public Direktor(Controller c, Eingang eingang, Ausgang ausgang) {
        this.c = c;
        this.ausgang = ausgang;
        this.eingang = eingang;
        new Thread(this).start();
        new Thread(eingang).start();
        new Thread(ausgang).start();
    }

    public void run() {
        try {           
            c.museumWirdGeoeffnet();

            Thread.sleep(500);

            c.rausKehren();

            c.museumWirdGeschlossen();
        } catch (InterruptedException e) {
            e.getStackTrace();
        }

    }

}
 

Jw456

Top Contributor
beim Verlassen musst du immer ein notify machen denn du willst ja das eventuelle gesperrte Kreutz freigeben.
das hattes du ja im anfangs code auch.
 

BodyLAB

Bekanntes Mitglied
beim Verlassen musst du immer ein notify machen denn du willst ja das eventuelle gesperrte Kreutz freigeben.
das hattes du ja im anfangs code auch.
Stimmt. Damit kann ich dann auch alles von notifyAll zu notify ändern. So gesehen kann ja dann immer nur der Eingang sich schlafen legen :)

Öhhh... ich hab den Direktor jetzt so geändert:
Java:
public class Direktor implements Runnable {
    private Controller c;
    private Eingang eingang;
    private Ausgang ausgang;

    public Direktor(Controller c, Eingang eingang, Ausgang ausgang) {
        this.c = c;
        this.ausgang = ausgang;
        this.eingang = eingang;
        new Thread(this).start();
    }

    public void run() {
        try {
            c.museumWirdGeoeffnet();
            if (c.museumOffen()) {
                new Thread(eingang).start();
                new Thread(ausgang).start();
            }
            Thread.sleep(500);

            c.rausKehren();

            c.museumWirdGeschlossen();
        } catch (InterruptedException e) {
            e.getStackTrace();
        }

    }

}

Wenn das Museum dann eben nicht offen ist bzw. Eingang und Ausgang noch nicht durch sind passiert eben nix. Man bekommt die Ausgabe Museum offen und Museum geschlossen fertig :D Dann hat das Museum keine Besucher an diesem Tag :-D

Könnte man dort nicht auch irgendwie durch eine Exception das ganze hin bekommen? Man wirft eine Exception und in der Fehlerbehandlung starten wir die Threads und dann sollte es auch laufen oder 🙃
 

Jw456

Top Contributor
Java:
public class Direktor implements Runnable {
    private Controller c;
  
    public Direktor(Controller c) {
        this.c = c;
        new Thread(this).start();
    }

    public void run() {
        try {
            
            c.museumWirdGeoeffnet();

            Eingang e = new Eingang(c);
            Ausgang a = new Ausgang(c);

            Thread.sleep(500);

            c.rausKehren();

            c.museumWirdGeschlossen();
        } catch (InterruptedException e) {
            e.getStackTrace();
        }

    }

    
}
 

BodyLAB

Bekanntes Mitglied
Super Danke :) Jetzt scheint es zu laufen. Zumindest hab ich es jetzt ca. 50x ausprobiert.
Auf die Simple Idee wie oben bin ich mal wieder nicht gekommen grrr...
Jetzt finde ich es sehr gut gelungen.
 

Jw456

Top Contributor
in der main mit deinem running Flag etwa so
Java:
Controller c = new Controller();
        Direktor d = new Direktor(c);

        while (!d.isRunning()) {                 }
        System.out.println("Direktor is Running");
        Eingang e = new Eingang(c);
        Ausgang a = new Ausgang(c);
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
ralfb1105 Frage zu Thread Synchronisation mit wait() und notify() Java Basics - Anfänger-Themen 3
M Umgang mit Thread/ Synchronisation/ Deadlock-Vermeidung Java Basics - Anfänger-Themen 5
P Thread Synchronisation Java Basics - Anfänger-Themen 9
T Thread Synchronisation Java Basics - Anfänger-Themen 3
Dit_ Thread Synchronisation | Übung Java Basics - Anfänger-Themen 5
M lock notify synchronisation Java Basics - Anfänger-Themen 8
A Ausgabe immer anders, synchronisation? Java Basics - Anfänger-Themen 2
hdi Synchronisation zwischen JList und ListModel Java Basics - Anfänger-Themen 6
hdi statische synchronisation Java Basics - Anfänger-Themen 6
1 JList Problem : Synchronisation mit Vector klappt nicht :( Java Basics - Anfänger-Themen 6
H Synchronisation von Threads Java Basics - Anfänger-Themen 12
Kr0e Synchronisation Java Basics - Anfänger-Themen 7
G Synchronisation Java Basics - Anfänger-Themen 8
A Thread Synchronisation Java Basics - Anfänger-Themen 10
M thread synchronisation Java Basics - Anfänger-Themen 6
L Problem bei Synchronisation von Threads Java Basics - Anfänger-Themen 3
S Sockets und Synchronisation Java Basics - Anfänger-Themen 7
U Synchronisation, Thread Java Basics - Anfänger-Themen 4
M Länge eines Arrays als Variable speichern möglich? Java Basics - Anfänger-Themen 14
P Objekt einer Methode eines anderen Objektes übergeben Java Basics - Anfänger-Themen 5
P Wie kann ich beispielsweise Speicherstände eines Spiels DAUERHAFT in meinem Programm speichern? Java Basics - Anfänger-Themen 3
laxla123 Eigenschaften eines Algorithmus (determiniert vs.. deterministisch) Java Basics - Anfänger-Themen 2
monsterherz Ablauf der Erstellung eines Java Programmes Java Basics - Anfänger-Themen 17
monsterherz Fehler Semikolon fehlt - ich weiss aber nicht wo da noch eines hin sollte... Java Basics - Anfänger-Themen 21
J Farbe des Striches eines TitledBorders ändern Java Basics - Anfänger-Themen 2
pc pc pc pc pc letztes Element eines Arrays n Java Basics - Anfänger-Themen 3
walid Öffnungszeiten eines Geschäftes Java Basics - Anfänger-Themen 3
paulen1 Best Practice "Unchecked Assignment" Warnung beim erstellen eines 2D Arrays of Arraylists Java Basics - Anfänger-Themen 2
T Probleme beim Import eines Git-Repos Java Basics - Anfänger-Themen 2
U Eigenschaft eines JTextfiels per ActionListener ändern... Java Basics - Anfänger-Themen 2
krgewb Breite und Höhe eines Bildes in base64 auslesen Java Basics - Anfänger-Themen 3
Sachinbhatt Was ist die Notwendigkeit eines Sammlungsframeworks in Java? Java Basics - Anfänger-Themen 2
N Textdatei aus Resourcen-Ordner eines Projekts/ jar-file lesen Java Basics - Anfänger-Themen 4
B Produkt eines double - streams Java Basics - Anfänger-Themen 3
B Attribute eines Objekts einer Klasse durch statische Methode einer 2. Klasse ändern? Java Basics - Anfänger-Themen 32
S Variablen Letzte Zeile eines Strings entfernen Java Basics - Anfänger-Themen 1
D Inhalt eines Arrays ausgeben Java Basics - Anfänger-Themen 7
A Jedes zweite Element eines Arrays entfernen Java Basics - Anfänger-Themen 30
sserio Java Fx, wie erstellt man einen EventHandler, der durch das Drücken eines Button Texte in eine Table view einfügt Java Basics - Anfänger-Themen 17
J Größe eines Strings in Pixel Java Basics - Anfänger-Themen 18
M Parse-Tree eines statements darstellen Java Basics - Anfänger-Themen 0
H Java verkettete Liste, Wert eines Index zurückgeben Java Basics - Anfänger-Themen 1
bluetrix Programmieren eines Bots für Zahlen-Brettspiel Java Basics - Anfänger-Themen 9
J Hinzufügen eines Objektes in ein Objekt-Array Java Basics - Anfänger-Themen 62
M Wie kann die Implementation einer Methode den Wert eines Attributs vermindern? Java Basics - Anfänger-Themen 3
A Rekursive Implementation eines Codes Java Basics - Anfänger-Themen 4
H String Repräsentation eines Rechtecks mit Instanz-Methode Java Basics - Anfänger-Themen 8
M Konstruktor ohne Übergabe eines Wertes Java Basics - Anfänger-Themen 7
M Wie kann ich in einem Konstruktor die Methode eines anderen Interfaces mit den jeweiligen Parametern aufrufen? Java Basics - Anfänger-Themen 8
M Wie erreiche ich das Vorwärtsgehen eines Roboters? Java Basics - Anfänger-Themen 2
M Wie erreiche ich es das Vorwärtsgehen eines Roboters? Java Basics - Anfänger-Themen 0
R While-Loop der die Einträge eines Arrays in umgekehrter Reihenfolge anzeigt Java Basics - Anfänger-Themen 3
A Optimierung eines Programms: Mergen der Dateien Java Basics - Anfänger-Themen 23
melisax Alle Möglichkeiten eines Wortes angeben Java Basics - Anfänger-Themen 3
A Java, verarbeitung eines xml-files Java Basics - Anfänger-Themen 2
C Fehler beim erstellen eines Objektes Java Basics - Anfänger-Themen 3
B Konkatenieren eines Strings und inkremtierenden Zahl zu einer INT Variablen Java Basics - Anfänger-Themen 7
F Initialisieren eines Web-Mp3 Players in Tabs durch "booleans" erst wenn Tab geöffnet wird ...? Java Basics - Anfänger-Themen 1
P Drei Zahlen eines Würfelspiels auswerten Java Basics - Anfänger-Themen 7
C Brauche Hilfe beim Schreiben eines Programmes :/ Java Basics - Anfänger-Themen 1
C initialisieren eines arrays richtiger Größe und mit geeignetem Datentyp Java Basics - Anfänger-Themen 26
C Überprüfen eines Programms auf Syntaxfehler Java Basics - Anfänger-Themen 3
S Wie kann ich den Bereich eines Integers begrenzen? Java Basics - Anfänger-Themen 2
nonickatall Grundsätzliches Verständnisproblem des Aufbaus eines Programms Java Basics - Anfänger-Themen 19
B Downgrade eines bestehenden Projektes Java Basics - Anfänger-Themen 5
amelie123456 Geschwindigkeit der Methode bewegeDich eines Objekts ändern Java Basics - Anfänger-Themen 2
D Hilfe beim Erzeugen eines Arrays NullPointerException wird ausgelöst Java Basics - Anfänger-Themen 11
J maximaler Wert eines Integers Java Basics - Anfänger-Themen 14
TimoN11 IntelliJ , Ausgabe von einem Quellcode in Eingabe eines Quellcodes Java Basics - Anfänger-Themen 1
Z Rückgabe eines Values in umgekehrte richtung Java Basics - Anfänger-Themen 5
L Methode zum invertieren eines Arrays Java Basics - Anfänger-Themen 7
B fragen zu Aufbau eines UML-Klassendiagramm Java Basics - Anfänger-Themen 1
eleonori Durchschnitt aller Werte eines Baums berechnen Java Basics - Anfänger-Themen 5
M Benutzereingabe eines Codes verbessern Java Basics - Anfänger-Themen 3
B Modulo-Operator anhand eines Beispieles erklären Java Basics - Anfänger-Themen 7
J Verschieben von Buchstaben in einem String um vorgegebene Anzahl von Zeichen innerhalb eines weiteren String Java Basics - Anfänger-Themen 12
F Auf Variablen eines Konstruktors zugreifen Java Basics - Anfänger-Themen 4
Kawastori Größe eines Arrays bestimmen Java Basics - Anfänger-Themen 13
Lena_2611 Vergleich von Array1 Index mit Array2 Wert und erzeugen eines neues Arrays Java Basics - Anfänger-Themen 8
A Teilarrays eines 2D-Arrays sortieren Java Basics - Anfänger-Themen 4
marcooooo Separator zwischen allen Zeichen eines Strings einfügen Java Basics - Anfänger-Themen 29
C Wie kann ich Versionen eines Projektes in Eclipse erstellen? Java Basics - Anfänger-Themen 3
yoskaem Text Color durch Klicken eines Buttons in anderer Activity ändern Java Basics - Anfänger-Themen 2
A Teilen eines Arrays Java Basics - Anfänger-Themen 5
DorFey Sortieren eines mehrdimensionalen Arrays Java Basics - Anfänger-Themen 8
P Klasse hat keinen Zugriff auf getter/setter-Methoden eines Objektes Java Basics - Anfänger-Themen 9
R Löschen und ausgeben eines Teilbaums Java Basics - Anfänger-Themen 3
J Alle Werte eines Strings zusammen addieren Java Basics - Anfänger-Themen 15
M Hilfe bei Strukturierung eines Buchungssystems Java Basics - Anfänger-Themen 3
M Erstellen eines insets Objekts, GridBagLayout Java Basics - Anfänger-Themen 13
M Rückgabe eines Arrays Java Basics - Anfänger-Themen 10
Z Erste Schritte Indexe innerhalb eines Arrays zusammensählen Java Basics - Anfänger-Themen 14
W Random Zahl unter Berücksichtung eines Durchschnitts Java Basics - Anfänger-Themen 7
N Länge eines Arrays in einem Objekt testen Java Basics - Anfänger-Themen 51
A Freie Stelle eines Arrays Java Basics - Anfänger-Themen 17
C Erstellen eines Widerstandsnetzwerks Java Basics - Anfänger-Themen 10
C Methode Seiten tauschen eines erstellten Rechtecks mit Seite A und B Java Basics - Anfänger-Themen 9
R Zugriff auf den Index eines Arrays, welches ein Objekt ist. Java Basics - Anfänger-Themen 4
J Problem bei der Programmierung eines Tannenbaums Java Basics - Anfänger-Themen 9
F Berechnung der Rektaszension und Deklination eines Sterns Java Basics - Anfänger-Themen 7

Ähnliche Java Themen

Neue Themen


Oben