Buffer - Consumer Producer - Threads synchronisieren

poochie89

Mitglied
Hallo,
hab wieder mal ne nette Aufgabe .
Gegebn sind eine Klasse Producer, Consumer (beide runnable) und UnsynchronizedBuffer. Der Producer schreibt nach zufälliger Zeit (zehn mal - schleife) in einen gemeinsamen Buffer den Consumer nach zufälliger Zeit ausliest (zehn mal - schleife). Der Producer addiert diese Werte und gibt sie zum schluss aus. Buffer auch. Natürlich ist das ganze nicht synchronisiert und es kann sein dass Consumer z.b. zwei mal den gleichen wert liest. Wir sollen nun mit Hilfe von synchronized, die Methoden in der Buffer Klasse synchronisieren (get und set). Aber synchronized stellt ja nur sicher dass ein Thread auf den anderen wartet sollte dieser gerade eine synchronized Methode ausführen und nicht dass beide abwechselnd schreiben und lesen.

Vielen Dank schon mal für die Hilfe
 
Zuletzt bearbeitet:
S

SlaterB

Gast
wenn ein Thread einen synchronized-Block betritt, dann sind ALLE synchronized-Blöcke auf dasselbe Monitor-Objekt für andere Threads gesperrt,

eine nicht-statische synchronisierte Methode ist ein entsprechend langer synchronized-Block auf das jeweilige Objekt
 

poochie89

Mitglied
wenn ein Thread einen synchronized-Block betritt, dann sind ALLE synchronized-Blöcke auf dasselbe Monitor-Objekt für andere Threads gesperrt,

jou das meinte ich ja oder verstehen ich gerade was falsch? führt ein thread eine synchronized methode eines objekts aus und ein zweiter thread will z.b. eine andere synchronized methode des gleichen objekts ausführen so wartet dieser bis der erste die methode fertig hat


Das get entfernt den gelesenen Wert aus dem Buffer, sodass dieser nicht doppelt gelesen wird.

ne das geht eben nicht weil wenn der consumer das get dann zweimal ausführt bekommt er einmal 0 und bekommt somit nicht alle zehn werte (weil di schleife im consumer ja nur zehn mal durchlaufen wird)


ohne dass ich da die klassen consumer und/oder producer ändere werde ich das ganze nicht lösen können oder?
 
S

SlaterB

Gast
> ohne dass ich da die klassen consumer und/oder producer ändere werde ich das ganze nicht lösen können oder?
mit welcher Begründung? (und was würdest du dann dort ändern?..)

wir stimmen überein dass synchronized blockiert, was brauchst du mehr?
 

xehpuk

Top Contributor
ne das geht eben nicht weil wenn der consumer das get dann zweimal ausführt bekommt er einmal 0 und bekommt somit nicht alle zehn werte (weil di schleife im consumer ja nur zehn mal durchlaufen wird)
Woher kommt denn da die 0? Wenn der Consumer get auf einen leeren Buffer aufruft, wartet er, bis der Producer auf den Buffer set macht.
Wie sieht der Buffer überhaupt aus? Beinhaltet er nur höchstens ein Element?
 

poochie89

Mitglied
also der buffer enthält nur einen integer, der eben mit get und set geschrieben und gelesen wird.

nehmen wir mal der producer schreibt in den buffer 1, producer schreibt 2, consumer liest 2...
da ist es ja egal ob die beiden methoden synchronisiert sind, wenn der producer eh 2 mal schreiben kann (was er ja darf wenn consumer noch nichts macht) ist das ganze eh schon futsch.
 
S

SlaterB

Gast
da stimme ich zu,

edit:
wobei der Buffer auch selber weiß ob er leer ist oder nicht und dann den Producer/ Consumer solange warten lassen könnte (wait/notify),
dann ist der synchronized-Block wieder für andere betretbar, das ginge auch ohne Producer/ Consumer-Änderung
 

poochie89

Mitglied
also würdest du auch sagen die Klassen Consumer und Producer müssen auf jeden Fall geändert werden?

edit: also du meinst ich könnte dem buffer den consumer und producer übergeben und dann gegebenenfalls anhalten bzw. weiter laufen lassen.
 
Zuletzt bearbeitet:

xehpuk

Top Contributor
Wenn der Buffer einfach nur so aussieht, dass er einen int hat, so könntest du bspw. noch einen boolean hinzufügen, der anzeigt, ob der Wert (neu) gesetzt wurde. In get/set wird dieser boolean dann immer überprüft, bevor der Wert gelesen/geschrieben wird.

Die Implementierung von Benutzern des Buffers sollte von diesem unabhängig sein.
 

poochie89

Mitglied
@xehpux
ja da ist aber wieder das gleiche problem, stell dir vor der producer schreib 1, setzt writingBlocked auf true, der producer will nochmal schreiben setzt nicht da wrtiningBlocked, die producerschleife läuft aber weiter und so wird 2 nie gesetzt....

@slate edit oben
und: werden bei einem wait() die synchronized einfach aufgehoben?!
 
S

SlaterB

Gast
ich meine dass du die lese und schreibe-Methoden nicht nur snychronized machen solltest, sondern diese beiden Methoden weiter veränderst so dass alles klappt,
damit wäre Änderung von Consumer und Producer nicht nötig, und die beiden müssen auch nicht im Buffer extra registiert werden oder ähnliches,
alle Aufrufe bleiben gleich, nur die beiden Methoden des Buffer ändern

> der producer will nochmal schreiben setzt nicht da wrtiningBlocked, die producerschleife läuft aber weiter und so wird 2 nie gesetzt....

hier müsste dann der Producer warten, bis der Consumer die Daten abgeholt hat
 
S

SlaterB

Gast
es geht immer um Threads, nie um Objekte,
wenn der Producer in die Methode kommt, dann ist der zugehörige Thread allumfassen präsent, man könnte ihn mit Thread.currentThread() abfragen,
aber das ist gar nicht nötig, ein Aufruf wait(); bedeutet genau dass der aktuelle Thread pausiert wird, schaue dir wait/ notify in Lehrbüchern an

mit dem Producer-Objekt könntest du an dieser Stelle sicher auch etwas anfangen,
dort eine Variable setzen, Methode beenden, dann bemerkt der Producer-Thread das vielleicht in seiner Producer-Verarbeitung,
das ist aber vergleichsweise aufwendig
 
Zuletzt bearbeitet von einem Moderator:

poochie89

Mitglied
aha, das hört sich gut an, notify weckt einfach den thread auf der gerade wartet, das macht das ganze natürlich einfach...
glaub jetzt hab ichs

danke für die ausführliche hilfe
 

Ähnliche Java Themen

Neue Themen


Oben