2.3: Sleepy Threads : Komische Ausgabe

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

2.3: Sleepy Threads : Komische Ausgabe
Hallo,
ich habe die Aufgabe Sleepy Threads bearbeitet. Die Ausgabe “Thread $N: Done” kommt auch jeweils eine Sekunde verzoegert. Ich verstehe nur bei meiner Ausgabe nicht, wieso die Threads nicht chronologisch ihren Schlaf verkuenden?
Meine Ausgabe fuer nThreads = 6 ist folgende:

Thread 1: Going to sleep
Thread 4: Going to sleep
Thread 5: Going to sleep
Thread 3: Going to sleep
Thread 2: Going to sleep
Thread 6: Going to sleep
Thread 1: Done
Thread 2: Done
Thread 3: Done
Thread 4: Done
Thread 5: Done
Thread 6: Done

Anhand der Done-Reihenfolge sieht man ja, dass sie in der richtigen Reihenfolge aufgerufen wurden. Wieso stimmt dann die erste Reihenfolge nicht? Kann mir das jemand erklaeren?


Ohne die genaue Aufgabe zu kennen:
Es wird daran liegen, dass die Threads vom System unterschiedlich geschedult werden, sprich eingelastet/ausgelastet werden. Dadurch das dem Scheduler egal ist welche Nummer dein Thread hat und hier Algorithmen hinter dem Scheduling stecken, die die Reihenfolge auch durcheinander werfen dürfen, können deine Threads eben auch asynchron ausgelastet werden. Wenn du dein Programm öfters ausführst wirst du feststellen, dass sich die Reihenfolge der Zahlen immer wieder ändert, wegen dem genannten Scheduler.

EDIT: Noch was vergessen: Wenn du Synchronisierungsmechanismen für deine Threads implementiert hast, wäre die Ausgabe durchaus nicht stimmig. Aber ich nehme mal an, dass die Dones zufällig in der richtigen Reihenfolge da stehen. Führe das Programm öfter aus und du wirst sehen, dass die Reihenfolge auch da kaputt geht.


Willkommen in der parallelen Programmierung :D.

Jase hat recht. Es ist auch beabsichtigt, dass die Ausgaben durcheinander gewürfelt sind.
Das zu verstehen ist Sinn der Übungsaufgabe ;).

Edit:
Das “Done” meistens in der richtigen Reihenfolge kommt, liegt an den sleeps mit den unterschiedlichen Zeiten.
Aber selbst die “Done” Ausgaben sind nicht immer in der richtigen Reihenfolge.
Du musst nur dein Betriebssystem gut genug beschäftigen damit das schief geht :cool:.


Danke fuer die schnellen Antworten.
Die ersten 6 Ausgaben sind wirklich durcheinander. Das habe ich jetzt so grob verstanden und muss nochmal drueber nachdenken.
Aber die letzten 6 Ausgaben muessen immer in der richtigen Reihenfolge sein, sonst verstehe ich gar nichts mehr?


Nein :D. sleep garantiert nur, dass ein Thread mindestens die angegebene Zeit wartet.
Wenn aber mehrere Threads länger als die 1s Abstand warten,
weil sie zum Beispiel vom Betriebssystem nicht gescheduled werden,
dann können sich die Reihenfolgen auch dort ändern.

Edit: deutsch -.-


Dann google ich mal und hoffe, dass es mir dann klar ist.
So langsam verstehe ich, wieso PFP nicht vom Computer korrigiert werden kann ^^


Ich habe es auch so, dass die Done-Ausgaben von 1-x geordnet erscheinen (erst 1, dann 2, dann 3,…).
Liegt das nicht daran, dass man erst join von Thread 1, dann von Thread 2, dann Thread 3,… aufruft?
Oder bin ich da noch auf dem falschen Dampfer? Thread1.join wartet doch erst mal auf jeden Fall, bis Thread1 fertig ist, oder?


Nein du wartest mit dem join() nur darauf, dass der Thread auf dem join() aufgerufen wurde beendet wird. Auf andere wird nicht gewartet.


Ah jetzt weiß ich wo dein Problem ist. Du glaubst, weil du nacheinander die Threads joinst muss auch die Ausgabe in der Reihenfolge so sein wie gejoint wurde. Das stimmt aber nicht. Das Problem bei der Sache ist, dass die Ausgabe im Thread erfolgt, d.h. du wartest mit Thread 2 nicht darauf, dass Thread 1 sein println() gemacht hat, sonden du wartest darauf, dass der Thread beendet wurde. Wird nun Thread 1 kurz vor der Ausgabe vom Scheduler ausgelastet und Thread
2 eingelastet+läuft durch bis nach dem println() und Thread 1 wird danach wieder eingelastet, dann hast du zuerste die Ausgabe von Thread 2 und dann die von Thread 1.


Hmm, klingt irgendwie sinnvoller und logischer als meine bisherige Sichtweise :smiley:
Aber warum schaffe ich es dann nie, dass die Done-Ausgaben nicht in geordneter Reihenfolge erscheinen (im Gegensatz zu den Going-to-sleep-Ausgaben)?

EDIT: Ich bin doof - da die Threads ja “id viele Sekunden warten” ist die Reihenfolge wieder logisch. Wenn man alle gleich lange warten lässt, dann kommt auch die Done-Ausgabe durcheinander. Da habe ich mich wieder selber übertroffen :stuck_out_tongue:


Gleich lange zu warten ist nicht nötig, es reicht, ungefähr gleich lange zu warten. Bei einem Unterschied von 1000 Millisekunden ist der Einfluss des Betriebssystems nicht so groß, bei einem Unterschied von 10 Millisekunden sieht die Sache ganz anders aus.


Muss man bei der aufgabe dafür sorgen dass das in der richtigen reihenfolge ist? oder ist dis ausgabe egal?

Außerdem hab ich mal aus spaß 1000 als parameter angegeben aber er erstellt dann nur 928 threads, warum?


Muss man nicht und soll man nicht ;).

Komisch, frag dazu mal nen Tutor in der Rechnerübung der deinen Code sehen kann. Eigentlich sollten 1000 auch gehen ;).


Im CIP? Da ist zumindest das Soft-Limit für die Anzahl der Prozesse 1000. Was tut Java denn, wenn es keine Threads mehr starten kann?


Einen OutOfMemoryError mit der Nachricht “unable to create new native thread” werfen.


Generell.
Man kann aus Yanniks Kommentar nicht schließen, ob es am Code liegt oder am gesetzten Prozess Limit ;).
In letzterem Fall hätte ich nämlich ne Fehlermeldung in Java erwartet :huh:.