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.
Aufgabe 7.4
Hey, zur c) eine Frage: Ist es erlaubt die äußere Zeile und die äußere Spalte außerhalb des Fließbandes zu füllen?
Ja, kann man machen. Optimal wäre es allerdings, man würde auch die Initialisierung im Fließband machen.
Womöglich steh ich bei der Aufgabe auf dem Schlauch, aber ich komm wirklich nicht drauf, wie man da effizient eine blockingqueue verwenden soll…
soll man je eine queue zwischen zwei threads stecken, um zu übergeben, wann wer seine nächste zeile berechnen darf, oder kann man das ganze sogar mit einer einzigen queue lösen? die eine variante scheint mir zu aufwändig, für die andre fällt mir keine gescheite lösung ein
Nehmen wir mal an, wir haben eine 6×6-Matrix und drei Threads. Dann kannst du die Berechnung folgendermaßen aufteilen:
1 | 2 | 3
X X | X X | X X
X X | X X | X X
X X | X X | X X
X X | X X | X X
X X | X X | X X
X X | X X | X X
Nehmen wir an, Thread 2 möchte den Eintrag an Stelle (2, 2) – in dieser Notation kommen erst Zeilen, dann Spalten – berechnen. Dafür werden die Einträge (1, 2), (1, 1) und (2, 1) benötigt. (1, 2) wurde von Thread 2 berechnet, aber die anderen beiden übernimmt Thread 1. Wenn Thread 1 (2, 1) berechnet hat, wurde sicher schon der Eintrag (1, 1) berechnet. Das heißt, Thread 1 muss Thread 2 jetzt mitteilen, dass (2, 1) berechnet wurde. Dazu fügen wir an den Grenzen in obigem Schaubild BlockingQueues ein. Jedes Mal, wenn Thread 1 seinen Teil einer Zeile fertiggestellt hat, legt er in die BlockingQueue, die konzeptuell „zwischen“ den Bereichen von Thread 1 und 2 liegt, ein Objekt. Dies signalisiert Thread 2, dass eine weitere Zeile von Thread 1 bearbeitet wurde.
Hi,
kann ich bei der Aufgabe a) davon ausgehen, dass die vorhergehenden Werte in der table schon berechnet wurden?
Hallo,
wie ist das denn bei der Aufgabe d) mit dem Exchanger. Haben wir das in der Vorlesung gemacht? ich habe es nicht finden können, könnte mir jemand sagen wo?
Im Internet gehen die ganzen Beispiele immer von nur zwei Threads aus, kann ich irgendwie steuern, welcher Thread mit wem austauscht? Oder wenn nicht, hätte jemand ne Idee wie man die Tabelle dann aufteilen könnte, das es nicht nötig ist?
Anstatt BlockingQueues kannst du Exchanger zwischen den Grenzen einfügen.
Ja, das ist mit der „teilweise befüllten“ Matrix gemeint.
Wie bau ich da die BlockingQueues ein bzw. woher weiß der Thread in welche Queue er gucken muss? Evlt. ein Array von BlockingQueues?
Irgendwie sowas würde naheliegen, da man offensichtlich mit einer nicht auskommt und man, wie du schon richtig sagst, sie ja irgendwie zuordnen muss.
Exchanger d)
Hallo miteinander,
ich bräuchte dringend mal Hilfe im Umgang mit den Exchangers, die Beispiele im Netz sind alle viel zu simpel, als dass es mir weiterhelfen würde…
Vielleicht hat ja die/der ein oder andere das gleiche Problem… die Funktionsweise von Exchanger hab ich verstanden und es ist auch naheliegend, dass man jeweils für zwei Threads die miteinander kommunizieren/tauschen sollen jeweils ein Exchanger Objekt braucht.
Die Exchanger Objekte wahrscheinlich mit einer Liste oder derartigem zuordnen?
ABER :
A: Wie beginne ich mit dem ersten Thread, da man ja das Arbeitsmaterial für die Threads erstmal zu Verfügung stellen muss, sprich dem ersten Thread die Tabelle aushändigen(ohne Exchanger zu verwenden, da ja z.b. wie in der 6x6 Matrix von “mkmdl” nur Exchanger zwischen den Threads vorhanden sind).
Das führt gleich zur nächsten Frage…B:
Wie soll man Objekte tauschen, wenn jeweils immer nur einer der an dem Exchanger teilhabenden Threads das Objekt eintauscht, dass der andere benötigt, dieser aber für den anderen keine nützliche Information hat(also ist ja einer immer voraus und der andere hätte ja nichts zum Tausch, da er noch gar nicht arbeiten konnte).
C: Was wäre ein Ansatz, nachdem alle Threads fertig sind, die Tabelle zurückzugeben…
Würd mich freuen wenn ihr mir aushelfen könntet hier…Grüße
A: Wie beginne ich mit dem ersten Thread, da man ja das Arbeitsmaterial für die Threads erstmal zu Verfügung stellen muss, sprich dem ersten Thread die Tabelle aushändigen(ohne Exchanger zu verwenden, da ja z.b. wie in der 6x6 Matrix von „mkmdl“ nur Exchanger zwischen den Threads vorhanden sind).
- Tabelle erstellen.
- Exchanger erstellen.
- Tabelle und Exchanger dem erstellten Thread als Referenz übergeben.
- Thread starten.
B:
Wie soll man Objekte tauschen, wenn jeweils immer nur einer der an dem Exchanger teilhabenden Threads das Objekt eintauscht, dass der andere benötigt, dieser aber für den anderen keine nützliche Information hat(also ist ja einer immer voraus und der andere hätte ja nichts zum Tausch, da er noch gar nicht arbeiten konnte).
Man übergibt dem anderen einfach irgendein Objekt ;).
C: Was wäre ein Ansatz, nachdem alle Threads fertig sind, die Tabelle zurückzugeben…
Join, Futures, AtomicInteger, CountdownLatch, Barrier…
Such dir was aus ;).
Hallo,
ich habe auch eine kleine Verständnis-Frage zum Exchanger.
Mein Ansatz ist, wie im Forum schon beschrieben, immer einen Exchanger “zwischen” zwei Threads zu legen.
Mein Gedanke dazu war, dass ich in jedem Thread zwei mal auf einen Exchanger zugreife, einmal, um den vorherigen Thread zu fragen ob die benötigte Zeile schon bearbeitet wurde und einmal um nach der Bearbeitung der Zeile dem nächsten mitzuteilen, dass die Zeile fertig ist.
Somit müsste ja jeder Thread nach seiner Mitteilung warten, bis sein Nachfolger mittels exchange fragt ob die Zeile bearbeitet wurde, oder?
Irgendwie scheint dass bei mir nämlich nie zu passieren und die Stelle nach dem “Mitteilen” wird nie erreicht.
Somit müsste ja jeder Thread nach seiner Mitteilung warten, bis sein Nachfolger mittels exchange fragt ob die Zeile bearbeitet wurde, oder?
Denk daran, dass der 0. Thread auf keinen Vorgänger warten muss und der letzte Thread nichts an irgend einen Nachfolger übergeben muss.
Das ist der häufigste Fehler an der Stelle ;).
Ich klinke mich auch noch kurz hier ein:
Bei dem Testfall testLargeQueue braucht meine Implementierung stolze 120 Sekunden und eine größere Heap-Size.
In der Spitze liegt die CPU-Auslastung bei 100 % und es werden ca. 2,5 GB Ram verwendet.
Ist das normal, oder bin ich unfähig?
Testfälle laufen durch, aber bei der testLargeQueue ist das ja eh eher ein Witz.
Ich klinke mich auch noch kurz hier ein:
Bei dem Testfall testLargeQueue braucht meine Implementierung stolze 120 Sekunden und eine größere Heap-Size.
In der Spitze liegt die CPU-Auslastung bei 100 % und es werden ca. 2,5 GB Ram verwendet.
Ist das normal, oder bin ich unfähig?
Das ist nicht normal. Die Musterloesung braucht auf meinem Rechner (ich war zu faul im CIP zu testen ;))
800mb und 0.5s.
Das ist nicht normal. Die Musterloesung braucht auf meinem Rechner (ich war zu faul im CIP zu testen ;))
800mb und 0.5s.
Ist es auch tatsächlich nicht, der Fehler liegt bei einer falschen Threadaufteilung. Im Grunde hat jeder Thread die ganze Arbeit gemacht.
insert facepalm here
ich schreibe zwar ein bisshen zu spät, aber vielleicht hat jemand eine Idee für mich: bei mir funktionieren alle tests in Levenstein, außer computeValue! es ist wirklich komisch, weil alle andere Methoden die Ergebnisse der computeValue-Methode brauchen. Und in JUnit bekome ich in computeValue-Test eine IndexOutOfBounds Exception…
Woran kann es liegen, wenn die Testfälle in 50-60 % der Fälle durchlaufen, in 40% der Fälle die MultipleThreadsQueue || Exchanger fehlschlagen und in 0-10% spontan irgendein Testfall :-/