Hallo Kollegen,
ich hab eine Profi-Java-Frage. Die kann wahrscheinlich auch nur jemand beantworten, der sich schon mal damit beschäftigt hat.
Und zwar gibts in Java das Schlüsselwort synchronized, mit dem ich kritische Bereiche vor gleichzeitigen Zugriff durch mehrere Threads schützen kann. Also z.B. damit nicht einer gleichzeitig in eine Variable was reinschreibt, während der andere die gerade ausliest.
So, dann gibts die Methode wait(), damit kann der Thread, der gerade in einem synchronized-Bereich ist, sich schlafenlegen und die Sperre kurzzeitig freigeben.
Andere Threads dürfen also in den synchronisierten Bereich eintreten. (Oder in einen anderen synchronisierten Bereich, der am selben Objekt synchronisiert wird.)
Der neue Thread kann jetzt notify() oder notifyAll() aufrufen, wenn er mit seiner Arbeit fertig ist und dann kann ein eventuell durch wait() wartender Thread weiterarbeiten.
Mein Problem ist jetzt, was genau ist der Unterschied zwischen notify() und notifyAll()?
notify() weckt zufällig genau einen wartenden Thread wieder auf.
notifyAll() weckt alle wartenden Threads auf, aber wie bei notify kann auch nur einer weiterarbeiten und die anderen werden durch die Sperre ausgesperrt und schlafen weiter.
Also genau dasselbe. Man kann nicht genau sagen, welcher von den Thread weiterarbeitet und es ist auch immer nur einer!
Jetzt steht im Buch "Java Threads" von Oaks/Wong, daß wenn mehrere Threads aufgeweckt werden, beispielsweise nur einer effektiv weiterarbeiten kann, weil die anderen etwa noch auf eine weitere Bedingung warten.
Eine deutsche Übersetzung/Zusammenfassung von dem Abschnitt gibt es z.B. unter:
http://www.informatik.fh-muenchen.de/~schieder/concurrent-java-ss99/03-schalk-wait-notify/main.htm
Und das Codebeispiel dazu unter:
http://www.informatik.fh-muenchen.de/~schieder/concurrent-java-ss99/03-schalk-wait-notify/ResourceThrottle.java
Leider geht das exakt an meiner Frage vorbei und die klären gar nicht, was nun der Unterschied ist oder ich hab einen Denkfehler!
Ich frag mich nämlich, wie Java das rauskriegen will, wer effektiv weiterarbeiten kann. Funktioniert das von alleine wie durch Zauberhand? Denn in den Threads selber werde ich ja sowas nicht einbauen können, da nur einer ausgeführt wird wegen der Sperre.
In einem anderen Buch (glaube in der Javainsel) hab ich noch einen anderen Denkansatz gefunden, der uns da vielleicht auch weiterhelfen kann. Und zwar gibt es für wait() folgendes Codemuster:
while (!condition)
try { wait(); } catch (InterruptedException e) {}
Wenn jetzt wait() aufgerufen wurde und später notify() oder notifyAll(), dann setzt der Thread nicht genau nach wait fort, sondern überprüft erst die Bedingung in der while-Schleife. Würde wait() innerhalb eines if-Blocks stehen, würde die Bedingung nicht erneut geprüft!
Ist das vielleicht schon die Lösung des Problems? Daß mehrere Threads bei notifyAll() aufwachen und die doch alle gleichzeitig von allein prüfen, ob die andere Bedingung (also !condition) noch erfüllt ist und dann einer von den Threds weiterarbeitet und die anderen aussperrt, für den das gilt?
Ist wie gesagt wohl ein Profi-Problem, aber vielleicht hat ja einer dazu eine Meinung oder dazu was in einer Vorlesung gehört?
danke
spunti
ich hab eine Profi-Java-Frage. Die kann wahrscheinlich auch nur jemand beantworten, der sich schon mal damit beschäftigt hat.
Und zwar gibts in Java das Schlüsselwort synchronized, mit dem ich kritische Bereiche vor gleichzeitigen Zugriff durch mehrere Threads schützen kann. Also z.B. damit nicht einer gleichzeitig in eine Variable was reinschreibt, während der andere die gerade ausliest.
So, dann gibts die Methode wait(), damit kann der Thread, der gerade in einem synchronized-Bereich ist, sich schlafenlegen und die Sperre kurzzeitig freigeben.
Andere Threads dürfen also in den synchronisierten Bereich eintreten. (Oder in einen anderen synchronisierten Bereich, der am selben Objekt synchronisiert wird.)
Der neue Thread kann jetzt notify() oder notifyAll() aufrufen, wenn er mit seiner Arbeit fertig ist und dann kann ein eventuell durch wait() wartender Thread weiterarbeiten.
Mein Problem ist jetzt, was genau ist der Unterschied zwischen notify() und notifyAll()?
notify() weckt zufällig genau einen wartenden Thread wieder auf.
notifyAll() weckt alle wartenden Threads auf, aber wie bei notify kann auch nur einer weiterarbeiten und die anderen werden durch die Sperre ausgesperrt und schlafen weiter.
Also genau dasselbe. Man kann nicht genau sagen, welcher von den Thread weiterarbeitet und es ist auch immer nur einer!
Jetzt steht im Buch "Java Threads" von Oaks/Wong, daß wenn mehrere Threads aufgeweckt werden, beispielsweise nur einer effektiv weiterarbeiten kann, weil die anderen etwa noch auf eine weitere Bedingung warten.
Eine deutsche Übersetzung/Zusammenfassung von dem Abschnitt gibt es z.B. unter:
http://www.informatik.fh-muenchen.de/~schieder/concurrent-java-ss99/03-schalk-wait-notify/main.htm
Und das Codebeispiel dazu unter:
http://www.informatik.fh-muenchen.de/~schieder/concurrent-java-ss99/03-schalk-wait-notify/ResourceThrottle.java
Leider geht das exakt an meiner Frage vorbei und die klären gar nicht, was nun der Unterschied ist oder ich hab einen Denkfehler!
Ich frag mich nämlich, wie Java das rauskriegen will, wer effektiv weiterarbeiten kann. Funktioniert das von alleine wie durch Zauberhand? Denn in den Threads selber werde ich ja sowas nicht einbauen können, da nur einer ausgeführt wird wegen der Sperre.
In einem anderen Buch (glaube in der Javainsel) hab ich noch einen anderen Denkansatz gefunden, der uns da vielleicht auch weiterhelfen kann. Und zwar gibt es für wait() folgendes Codemuster:
while (!condition)
try { wait(); } catch (InterruptedException e) {}
Wenn jetzt wait() aufgerufen wurde und später notify() oder notifyAll(), dann setzt der Thread nicht genau nach wait fort, sondern überprüft erst die Bedingung in der while-Schleife. Würde wait() innerhalb eines if-Blocks stehen, würde die Bedingung nicht erneut geprüft!
Ist das vielleicht schon die Lösung des Problems? Daß mehrere Threads bei notifyAll() aufwachen und die doch alle gleichzeitig von allein prüfen, ob die andere Bedingung (also !condition) noch erfüllt ist und dann einer von den Threds weiterarbeitet und die anderen aussperrt, für den das gilt?
Ist wie gesagt wohl ein Profi-Problem, aber vielleicht hat ja einer dazu eine Meinung oder dazu was in einer Vorlesung gehört?
danke
spunti