FB18 - Das Forum für Informatik

fb18.de / Diplom Informatik / Unterbereich Grundstudium / Praktische Informatik

synchronized-wait()?!

synchronized-wait()?! 2006-01-27 16:12
Lazy
Ich habe eine Frage zu synchronized und wait(). Dazu erstmal ein Stück Programmtext aus dem Skript. Es ist eine Implentation der Pufferverwaltung:

class BufferImpl implements Buffer { protected Object[] buf; protected int in = 0; protected int out = 0; protected int count = 0; protected int size; BufferImpl(int size) { this.size = size; buf = new Object[size] } public synchronized void put(Object o) throws InterruptException { while (count == size) wait(); buf[in] = o; ++count; in = (in+1) mod size; notify(); } public synchronized Object get() throws InterruptException { while (count == 0) wait(); Object o = buf[out]; buf[out] = null; --count; out = (out + 1) mod size; notify(); return (o); } }
Also ich habe synchronized so verstanden, dass Java dafür sorgt, dass zwei synchronized Methoden (bzw. Blöcke) nicht gleichzeitig ausgeführt werden können. Wenn ich nun aber get() aufrufe und der Puffer ist leer, dann wartet er ja so lange, bis er einen notify bekommt und der Puffer nicht mehr leer ist. wie kann denn aber der Puffer gefüllt werden, wenn die put(Object) Methode auch synchronized ist? Die beiden Methoden können doch gar nicht gleichzeitig ausgeführt werden!? Oder bewirkt wait(), dass nun auch wieder andere synchronized Methoden/Blöcke ausgeführt werden können?
Oder habe ich irgendwas falsch verstanden?

Re: synchronized-wait()?! 2006-01-27 17:02
Faleiro
My two cents, ohne allzuviel Zeit mit deinem Codebeispiel verbracht zu haben: Der 'lock' am Objekt wird nicht etwa freigegeben, nur weil du wait() ausfuehrst. Tatsaechlich dauert der 'lock' an, bis die Methode vorbei ist. Insofern bietet es sich wohl an, die gelockten Bereiche staerker einzugrenzen, um also bei Nichtvorhandensein der Daten erstmal wieder freizugeben…

Die beiden Methoden können doch gar nicht gleichzeitig ausgeführt werden!?
Nur, um begrifflich korrekt zu bleiben: Sie koennen nur nicht *am selben Objekt* gleichzeitig ausgefuehrt werden. (Was fuer dein kleines Beispiel wohl keinen Unterschied macht.)

AFAIK :)

Re: synchronized-wait()?! 2006-01-27 17:20
Lazy
ich hab mich gerade nochmal ein bißchen schlau gemacht: anscheint gibt wait() den lock doch frei:
Wartet ein Thread auf eine Nachricht, dann versetzt er sich mit wait() in eine Art Trance. Er geht in den Zustand nicht ausführend über und gibt für diesen Zeitraum seinen Monitor frei. Würde der wait() aufrufende Thread den Monitor nicht freigeben, könnte er auch nicht von anderen Threads reserviert werden. Somit könnte kein anderer Thread synchronisierten Programmcode ausführen, da ja der Monitor belegt ist und normalerweise sichergestellt sein muss, dass sich nur ein Thread im kritischen Abschnitt befindet.
das wäre dann wohl auch des "Rätsels" Lösung

Re: synchronized-wait()?! 2006-01-27 17:31
Faleiro
Wartet ein Thread auf eine Nachricht, dann versetzt er sich mit wait() in eine Art Trance. Er geht in den Zustand nicht ausführend über und gibt für diesen Zeitraum seinen Monitor frei.
das wäre dann wohl auch des "Rätsels" Lösung
Oha, da hab ich in einem Forum anderslautende Auskunft gefunden. Danke, sehr interessant. Insbesondere irgendwie gefaehrlich, wenn man das Gegenteil glaubt :)

Re: synchronized-wait()?! 2006-01-27 18:46
Tzwoenn
Wie wäre es einfach mal mit API lesen:

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#wait(long)

Da steht alles drin.

Re: synchronized-wait()?! 2006-01-27 18:56
Brokkoli
wenn wait nicht freigeben würde, wäre eine derartige konstruktion ja nicht möglich. wait kann man ja nur in einem synchcronized block aufrufen.

Re: synchronized-wait()?! 2006-01-27 20:20
Tzwoenn
wenn wait nicht freigeben würde, wäre eine derartige konstruktion ja nicht möglich. wait kann man ja nur in einem synchcronized block aufrufen.

notify() übrigens auch [img]http://www.fb18.de/gfx/23.gif[/img]

Re: synchronized-wait()?! 2006-01-28 01:59
Anonymer User
Noch ein paar Hinweise:

Statt notify() ist meist notifyAll() besser.

Wer auch nur minimal nebenläufige Programme in Java schreiben will, sollte sich mal das Buch "Concurrent Programming in Java: Design Principles and Pattern" angucken. Das ist sowohl gut zu lesen als auch sehr informativ. Kent Beck sagte mal: "Der Java-Compiler sollte eine Fehlermeldung ausspucken, wenn jemand versucht Runnable zu implementieren, ohne dass er dieses Buch gelesen hat". Einzige Haken: Das Buch hat schon ein paar Jahre auf dem Buckel und berücksichtigt zum Beispiel das Nebenläufigkeitspaket im jdk 1.5 nicht. Zumindest nicht direkt, denn in dem Buch werden Klassen beschrieben, die jenem aus 1.5 verdammt ähnlich sehen, da der Autor des Buches auch der Autor der Klassen im jdk ist. Bleibt zu hoffen, dass er auch zu dem Buch irgendwann mal eine neue Auflage rausbringt, wobei das aber auch nicht _so_ wichtig ist, da der Großteil seine Gültigkeit behalten hat und der Autor den Rest auf der Seite zum Buch beschreibt.

Auch das Buch "Effective Java™ Programming Language Guide" ist zwar mittlerweile ein wenig angestaubt aber noch immer hervorragend und enthält ein paar Abschnitte zu Nebenläufigkeit.

LEIFer

Re: synchronized-wait()?! 2006-01-28 17:44
Tzwoenn
Ist nebenläufige Programmierung nicht Teil des P-Zyklus… oder wie das ganze jetzt im Bachelor auch immer heißen mag? Ich erinner mich irgendwie dunkel an nervige Debuggingsessions in tiefer Nacht (kurz vor'm Abgabetermin der jeweiligen Hausaufgabe).

Re: synchronized-wait()?! 2006-01-28 18:17
TriPhoenix
Ich schätze mal in SE2

Re: synchronized-wait()?! 2006-01-28 19:38
Lazy
In P3 wurde es kurz angerissen. Also so die wichtigsten Grundlagen wurden vermittelt.
Deswegen ja auch meine Frage, da ich grad am P2/3 lernen bin.