mulithreads wann ist synchronized notwendig?



  • Guten Tag,
    mein Problem ist eigentlich das ich selbst nach einigen online Tutorials und ein paar Büchern nicht vollständig verstanden habe wann es zu Problemen zwischen zwei threads kommen kann. Ich hab soweit gelernt das selbst ++i nicht atomar ist, sprich wenn ich zwei threads habe die beide eine variable erhöhen ist die Wahrscheinlichkeit das ganz schief geht gegeben. Aber wie sieht das mit einem schreibenden und einem lesenden thread aus? sprich thread 1 setzt einen int auf 20 und thread 2 handelt dem entsprechend. Oder wie sieht das mit den collections aus? thread 1 wirft Objekte rein und thread 2 holt sie wieder raus? Gibt es da irgendwie konkrete regeln wann man den Datenaustausch zwischen 2 threads besonders schützen muss? Was ich eigentlich immer lese ist, viele threads machen unter umständen das ganze schneller(der Benutzer ist halt doch immer der langsamste) aber unnötige synchronzied Blöcke machen das ganze dann um so schneller wieder wett.

    Noch als weitere Frage, gibt es irgendwelche Größenordnungen in denen sich die Anzahl der Threads noch befinden sollte? sprich sind 10 threads schon viel zu viel oder könnte man auch ohne weiteres mal ein paar hundert haben?

    mfg
    Turmfalke



  • Turmfalke_ schrieb:

    Aber wie sieht das mit einem schreibenden und einem lesenden thread aus? sprich thread 1 setzt einen int auf 20 und thread 2 handelt dem entsprechend.

    Kann auch schiefgehen, muss synchronisiert werden!
    Beispiel:
    angenommen deine Architektur kann 32 Bit auf einmal schreiben (z. B. x86). Du willst jetzt einen long long (64 Bit) von 0 auf auf -1 setzen (also 0xFFFF....FFFFF).
    Thread A schreibt, Thread B liesst den Wert. Ok, Thread A faengt an, und setzt die ersten 32 Bit (die CPU kann ja nicht alle 64 Bit auf einmal setzen): 0x0000...FFFFF. Jetzt wird Thread A unterbrochen, Thread B kommt zum Zug und liesst einen Wert, den es gar nicht geben duerfte (naemlich 0x0000....FFFF).

    Oder wie sieht das mit den collections aus? thread 1 wirft Objekte rein und thread 2 holt sie wieder raus?

    Muss synchronisiert werden (aus dem gleichen Grund wie oben).

    Gibt es da irgendwie konkrete regeln wann man den Datenaustausch zwischen 2 threads besonders schützen muss?

    Wenn 2 Threads auf die gleichen Daten zugreifen koennen, und mindestens 1 der Threads auf die Daten schreibend zugreift, musst du synchronisieren!

    Noch als weitere Frage, gibt es irgendwelche Größenordnungen in denen sich die Anzahl der Threads noch befinden sollte? sprich sind 10 threads schon viel zu viel oder könnte man auch ohne weiteres mal ein paar hundert haben?

    kommt drauf an, wieviel Arbeit die Threads haben. Wenn die Threads alle nur im Hintergrund auf Aktionen warten und kaum was tun, kannst du auch 100 davon haben (allerdings steigt der Verwaltungsaufwand fuer das OS).
    Wenn alle Threads rechnen (z. B. Number Chrunching) dann bringen mehr als ~#Anzahl CPUs + 1 wenig (das ist jetzt eine grobe Orientierung, keine goldene Regel). Wenn die Threads allerdings nicht andauernd die CPU benoetigen, sondern hin & wieder auch I/O machen oder sonstwas, kann es sich lohnen, die Anzahl Threads entsprechend zu erhoehen.



  • ok, dank dir vielmals.



  • Blue-Tiger schrieb:

    Turmfalke_ schrieb:

    Aber wie sieht das mit einem schreibenden und einem lesenden thread aus? sprich thread 1 setzt einen int auf 20 und thread 2 handelt dem entsprechend.

    Kann auch schiefgehen, muss synchronisiert werden!
    Beispiel:
    angenommen deine Architektur kann 32 Bit auf einmal schreiben (z. B. x86). Du willst jetzt einen long long (64 Bit) von 0 auf auf -1 setzen (also 0xFFFF....FFFFF).
    Thread A schreibt, Thread B liesst den Wert. Ok, Thread A faengt an, und setzt die ersten 32 Bit (die CPU kann ja nicht alle 64 Bit auf einmal setzen): 0x0000...FFFFF. Jetzt wird Thread A unterbrochen, Thread B kommt zum Zug und liesst einen Wert, den es gar nicht geben duerfte (naemlich 0x0000....FFFF).

    Ist die Java VM so hardwarenah? Sollte die nicht Hardwarespezifische Probleme weg kapseln?



  • hmmmm?? schrieb:

    Ist die Java VM so hardwarenah? Sollte die nicht Hardwarespezifische Probleme weg kapseln?

    Und wie?
    Soll die VM jeden Schreibzugriff synchronisieren?

    Ne, wenn du schreibst und wer anderen lesen will muss man synchronisieren. Java bietet hier zB aber atomic Klassen an.



  • ich empfehle gleich einmal
    Java Concurrency in Practice

    da wird z.B. in 3.1.2 geklärt, dass
    double und long volatile deklariert werden sollten oder von einem lock geschützt werden

    neben atomicLong und atomInteger...

    gibt es für die listen und andere datenstrukturen des collection frameworks im
    java.util.concurrent package klassen die man nutzen sollte

    und persöhnlich glaube ich, wenn man nicht wirklich ein geschwindigkeitsvorteil dringend benötigt, aber ein möglichst fehlerfreies programm, dann sollte man die finger davon lassen, denn das oben genannte buch hat mir gezeigt, dass es mit synchronized alleine selten getan ist, sondern, dass es scheiße schwer ist



  • Ansonsten implementiert Java ja auch das Prinzip der Monitore


Log in to reply