Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
wir haben eine Aufgabe bekommen und ich kann leider nicht so wirklich etwas damit anfangen.
Die Aufgabenstellung lautet:
Implementieren Sie einen Monitor in Java.
Dieser Monitor verfügt über eine Synchronisierungsmethode, die sicherstellt das eine Anzahl von n Threads diese Methode aufrufen müssen bevor diese fortfahren können.
Testen Sie Ihre Überwachung der Implementierung innerhalb eines ausführlichen Java-Programms mit unterschiedlichen Werten für n.
Bitte geben Sie bei jeder Statusänderung des Monitors eine Meldung auf der Konsole aus.
Bedeutet das, dass ich eine Schranke (Monitor) benötige, der Threads empfängt n-Stück. Sobald er diese zusammen gesammelt hat dürfen die Threads wieder weiter laufen?
Also eine Klasse, nenn ich sie mal Threads erzeugt 20 Threads. Diese zahl 20 muss die Schranke wissen. Die Schranke sammelt die Threads ein, wartet bis alle da sind. Sobald alle 20 Threads in der Schranke sind, gibt die Schranke die Threads wieder frei und diese laufen dann einfach wieder weiter. Wäre das so richtig oder wie kann man das noch verstehen?
Also die Aufgabe würde ich jetzt auch so verstehen. Aber der Begriff Monitor passt da aus meiner Sicht nicht richtig. Da habe ich eine etwas andere Vorstellung - wie sie z.B. in https://de.wikipedia.org/wiki/Monitor_(Informatik) beschrieben wurde.
Aber da kann evtl. jemand anderes deutlich mehr zu sagen - mein Studium ist deutlich zu lange her und in dem fachlichen Bereich habe ich so eigentlich nichts zu tun gehabt all die Jahre ...
Danke @KonradN. Dann hätte ich nun ein altbekanntes Problem erneut :-( So vermute ich mal.
Hier mal mein Anfang. Ist natürlich Quatsch
Java:
public class Schranke {
private int n, i = 0;
public Schranke(int n) {
this.n = n;
}
public synchronized void warten() {
try {
while(i < n) {
System.out.println("Der " + i++ + " Thread wartet in der Schranke.");
wait();
}
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Die Threads laufen weiter!");
notifyAll();
}
}
Das notifyAll() würde ja nie erreicht werden etc. deswegen ist das natürlich Quatsch.
Also hab ich hier erneut das Problem wenn die Variable erreicht wird und n Threads vorhanden sind müsste die Schranke erkennen: "Hey ich sollte jetzt alle Threads wieder wecken". Funktioniert so etwas? Falls NEIN ist mein Ansatz schon Falsch.
Anders hätte ich gerade keine Idee an solch eine Sache ran zu gehen.
Mir ist gerade noch so etwas eingefallen.
Java:
public synchronized void warten() {
try {
while(i < n) {
System.out.println("Der " + i++ + " Thread wartet in der Schranke.");
if(i == n -1)
notifyAll();
wait();
}
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Die Threads laufen weiter!");
notify();
}
Weiß nur nicht ob es wirklich so läuft wie es laufen soll Außerdem haben wir gelernt das wait() und notify() pärchenweise auftreten sollen. Hier hätte ich aber nur ein wait und zweimal notify sogar notifyAll und notify
Du brauchst in dem Monitor keine While Schleife. Dort betrachtest Du ja den Weg, den ein Thread geht. Die Schleife brauchst Du nur bei der Methode für den Test, denn da sollst Du ja n Threads erzeugen.
Was soll denn ein Thread machen, wenn er da rein kommt?
- Als erstes wollen wir diesen zählen.
- Dann kann es sein, dass die Anzahl der Threads noch zu gering ist. Was macht er dann? (Hast Du prinzipiell schon)
- Wenn es der n-te Thread ist: Was machen wir dann? Zwei Dinge sind zu machen. Eine Sache hast Du vom Prinzip an falscher Stelle schon, aber eine zweite Sache fehlt noch. Hierzu ggf. einfach mal durchspielen, was passiert, wenn der (n+1)-te Thread kommt.
Und ein Thema hatten wir letzte Mal etwas diskutiert (Du erinnerst Dich evtl., noch - ist ganz leicht eskaliert): Wenn mehrere Threads auf eine Variable zugreifen, dann macht es prinzipiell Sinn, diese Variable leicht anzupassen (Auch wenn es für eine Nutzung rein in synchronized Methoden vermutlich nicht notwendig ist).
Aber ich würde klar dazu raten, die Anpassung vorzunehmen.
Hab es nun so gemacht. Eine Klasse Threads, die erstellt N Threads, diese laufen dann in die Schranke und müssen dort erstmal warten bevor es weiter geht.
Java:
public class Threads extends Thread {
private Schranke s;
public Threads(Schranke s, String name) {
super(name);
this.s = s;
}
public void run() {
s.warten();
}
public static void main(String[] args) {
int n = 10;
Schranke s = new Schranke(n);
for (int i = 0; i < n; i++)
new Threads(s, "Nr. " + i).start();
;
}
}
Java:
public class Schranke {
private int n, count = 0;
public Schranke(int n) {
this.n = n;
}
public synchronized void warten() {
try {
count++;
System.out.println("Es wartet derzeit " + count + " Thread in der Schranke.");
Thread.sleep(500);
if (count == n)
notifyAll();
else
wait();
System.out.println("Der " + count-- + " Thread laueft wieder weiter.");
} catch (InterruptedException e) {
System.out.println(e.getStackTrace());
}
}
}
Was ich leider nicht verstehe ist, wenn ich einem Thread einen Namen übergebe, wie könnte ich diesen Namen abgreifen? Glaube es geht sicherlich dann nur so, dass man jeden Thread an die Schranke übergibt. Diese dann in einer Datenstruktur verwahrt und könnte dann z. B. Threads[] t; t[0].getName(); aufrufen.
Wenn ich mehr als N Threads habe, wird irgendwann ein Thread frei somit kann der nächste Thread in die Schranke laufen etc. die Abfrage if (count == n) wird nicht mehr erfüllt und alle warten ewig.
Wie viele Threads sind denn "im Monitor", nachdem der n-te Thread drinnen war? Wenn Du das sagen kannst, dann könntest Du den Zähler ja entsprechend umsetzen.
Oder evtl. ist es einfacher, denn Du Dir überlegst:
Beim Eintritt / am Anfang zählst Du den Zähler hoch ... da könnte man dann ja am Ende / vor dem Verlassen evtl. irgend etwas anderes machen ....
Mein Problem ist das ich nicht weiß wie die Threads weiter machen, die in der Schranke sind.
Hab auch versucht den count = 0 zu setzen wenn ich notifyAll() aufrufe. Das geht aber auch nicht
Wie viele Threads sind denn "im Monitor", nachdem der n-te Thread drinnen war? Wenn Du das sagen kannst, dann könntest Du den Zähler ja entsprechend umsetzen.
Nach dem der n-te Thread drin ist, sind 10 Stück drin. Dann ruft dieser notifyAll auf und setzt den count-- eins runter. Somit sollten dann noch 9 Stück drin sein oder ist das auch schon falsch? Da ist ja mein Problem, dass dann ja einer der vielen anderen Threads zum zuge kommt und dann eben später nichts mehr geht
Kann man das Problem irgendwie so lösen, dass wir die Schranke erst füllen und dann wieder leeren. Das ganze macht man dann so lange bis keine Threads mehr über sind. Die anderen Threads die zu viel sind müssen eben eh immer Schlafen, bis die Schranke leer ist. Dann bräuchte ich noch einen Zähler der sagt wie viele Threads in der Schranke gerade sind.
Wie sah das im Code denn aus? Denn genau das sollte es eigentlich sein.
Die andere Möglichkeit wäre, dass jeder Thread beim verlassen immer count um eins reduziert. Aber da kann es Nebeneffekte geben, denn die schlafenden Threads müssen nach dem wait ja erst mal weiter machen. Ggf. kommt aber noch ein Thread rein und dann wäre count == n womöglich schon wieder wahr. Daher ist die Idee, count auf 0 zu setzen, im Augenblick die richtige Lösung.
public class Schranke {
private int n, count = 0;
public Schranke(int n) {
this.n = n;
}
public synchronized void warten() {
try {
count++;
System.out.println("Es wartet derzeit " + count + " Thread in der Schranke.");
//Thread.sleep(50);
if (count == n) {
count = 0;
notifyAll();
}
else
wait();
System.out.println("Der " + count-- + " Thread laueft wieder weiter.");
} catch (InterruptedException e) {
System.out.println(e.getStackTrace());
}
}
}
Ich hab nur in der If Bedingung den count = 0 gesetzt.
Die Ausgabe zeigen auch das es so nicht geht, denn wir kommen in den negativen bereich wodurch wir erneut Blockiert werden könnten.
Hab ich count = 0 an der Falschen stelle?
Ich habe Dir zwei Ideen genannt, von der Du entweder die eine oder die andere umsetzen sollst. Aber nicht beide gleichzeitig!
Wenn Du count auf 0 setzt, dann darfst Du es nicht mehr reduzieren.
Ich habe Dir zwei Ideen genannt, von der Du entweder die eine oder die andere umsetzen sollst. Aber nicht beide gleichzeitig!
Wenn Du count auf 0 setzt, dann darfst Du es nicht mehr reduzieren.
Okay. Für mich sieht die Sache jetzt auch Logisch aus
____
Wird heute auch noch so Programmiert oder gibt es dafür nicht Objekte die das ganze Kapseln? Auch wenn dann die Parallelität etwas eingeschränkt werden sollte das kann man doch an sich in Kauf nehmen oder?
Wird heute auch noch so Programmiert oder gibt es dafür nicht Objekte die das ganze Kapseln? Auch wenn dann die Parallelität etwas eingeschränkt werden sollte das kann man doch an sich in Kauf nehmen oder?
Also meiner Meinung nach sind das Grundlagen, die Du einmal lernen sollst und die Du vermutlich später nie mehr selbst programmieren wirst.
Aber das Wichtige ist das Verständnis. Und dazu ist auch das Doing wichtig, weil so prägt sich das deutlich besser ein.
Generell gibt es viele Klassen, die hier Dinge bieten, aber die Frage ist wirklich, was Du entwickelst. Gerade in Java hast Du in den meisten Anwendungsgebieten damit nicht viel am Hut.
Also meiner Meinung nach sind das Grundlagen, die Du einmal lernen sollst und die Du vermutlich später nie mehr selbst programmieren wirst.
Aber das Wichtige ist das Verständnis. Und dazu ist auch das Doing wichtig, weil so prägt sich das deutlich besser ein.
Generell gibt es viele Klassen, die hier Dinge bieten, aber die Frage ist wirklich, was Du entwickelst. Gerade in Java hast Du in den meisten Anwendungsgebieten damit nicht viel am Hut.
Liest hier noch jemand weiter? Ich hätte noch eine Aufgabe und wieder ein MEGA Problem 😔
Aufgabe:
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.
Ich hätte bei der Aufgabe 5 Klassen (am Anfang eher 6), einen Eingang, Ausgang, Leiter, Controller, Besucher (Anfangs: Museum).
Der Eingang und Ausgang sind Monitore, Besucher und Leiter sollten Threads sein.
Nun dachte ich Anfangs an Museum weil ich nicht weiß wie ich die maximale Anzahl der Besucher sonst organisieren kann. Nun hätte ich alles in den Controller gepackt. Doch da hätte ich das selbe Problem wie mit der Museums Klasse. Wie bekomme ich in der Eingangs- und Ausgangs Klasse die maximale Anzahl verteilt. Sprich wenn der Controller ein int max = 50 hat, sollte der Eingang ja erkennen ab 50 lasse ich niemand mehr rein, nach einer gewissen Zeit sollte jemand aus dem Museum raus gehen. Dann muss der Controller max -1 machen etc.
Kann mir das jemand vielleicht erklären oder ist meine ganze Annahme komplett falsch!!!