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
Hallo,
wie ist denn bei dem MSCLock das mit der verketteten Liste gemeint?
Wo trägt sich der Thread denn in die Warteschlange ein und wie kann es sein, dass er das atomar macht?
Danke!
Andere Frage: sind eigentlich die Klassen aus java.util.concurrent verwenden? (bei mir Future & FutureTask), oder verienfachen die alles zusehr?
@ Chefchen
die Klasse QNode hat ein
QNode next
feld.
Das sieht für mich wie eine einfach verkettete Lsite aus.
und mit dem Ende könnte
private AtomicReference<QNode> tail
gemeit sein. Da das eine AtomicReference ist, kann man sie atomar umlegen
V AtomicReference<V>.getAndSet(V update)
Was will ich den mit dem Ende bei einer einfach verketteten Liste?
Ich glaub eher das mit tail das erste Element der Liste gemeint ist (auch wenn das namestechnisch etwas verwirrend wäre). Dann kann ich was an die Liste anhängen allerdings nicht atomar, aber man könnte ein synchronized verwnenden (falls man das darf).
Ansonsten bin ich von der Aufgabenstellung auch verwirrt
Und auch wenn mich jetzt viellecht gleich jemand für dumm hält, wo find ich denn die ListNodeImpl für die d) ?
Das tail ist schon das Ende der Queue.
Die Idee ist in etwa folgende:
tail zeigt immer auf das letzte Element, das sich in die Queue eingetragen hat. Möchte ich mich also an die Queue anhängen, dann setze ich mich selbst als tail ein und setze den next-Zeiger meines Vorgängers auf mich.
Somit weiß jeder Vorgänger durch seinen next-Zeiger, wer sich unmittelbar nach ihm eingetragen hat und durch das tail-Element kann sich jedes eingefügte Element ans Ende anhängen. Und damit ergibt sich das für einen Queue gewünschte FIFO Prinzip.
Danke so funktioniert das richtig toll
Der Testcase testSortetList dauerd bei mir mit dem MCS-Lock ca 5 mal solange wie mit den andern beiden locks.
Kann das hinkommen? Ich benutze in der unlock() Methode compareAndSet bremst das vielleicht so aus?
Hallo, mal ne Frage:
Hab jetzt die a) fertig und die testcases dazu laufen auch fast alles, bis auf den testSortedList, der klappt nur sehr selten. Wenn er fehl schlägt fehlt immer genau ein Knoten…
z.B. so: java.lang.AssertionError: expected:<12461> but was:<12460>
java.lang.AssertionError: expected:<26373> but was:<26372>
jemand ne Ahnung was ich falsch mache??
testSortedList funktioniert erst wenn du die d) gemacht hast.
Habs auch grade gesehen Oo. Hat mich nur gewundert weils manchmal so schon funktioniert. Trotzdem Danke!
Hmm bin jetzt bei C), aber ich muss sagen ich verstehe das mit dem QNode auch noch nicht so ganz
Ich hab mir jetzt schon die ganzen beiliegenden Klassen durchgesehen und denke ich auch halbwegs deren Sinn erfasst. Aber wo soll jetzt zum Beispiel das hasLock Feld in QNode sein?
@NeubauMa
das boolean hasLock sagt einfach aus, ob der QNode grad das Lock hält, oder nicht
is z.b. hilfreich, um beim unlock festzustellen, ob er überhaupt das Lock hat, oder beim locken festzustellen, ob er schon das lock hat, oder noch in der Warteschlange steckt;
Ich stehe grade etwas auf dem schlauch. erste aufgabe: CASLock
wie komm ich an den currentThread - klar mit der currentThread methode- aber auf was wende ich die methode an?
EDIT: hat sich geklärt. angabenblatt genau lesen…
kleine Frage
Hallo,
habe mal eine kleine Frage, darf man
if (…) while (…);
als Einzeiler schreiben, wenn möglich, oder gibt es dafür Punktabzug?
kleine Antwort
Warum sollte es das? Du kannst deinen Kode so hinschreiben, wie du ihn für am schönsten hällst, solang er funktional korrekt ist.
Und am besten schreibst du noch einen Kommentar wie „Java-Syntax aus der Hoelle“ (in PFP eigentlich auch ASCII-only?) dazu.
MCSLock.lock():
Wenn die Liste nicht leer ist und ein anderer Thread das Lock hält, wie finde ich ihn dann, wenn ich doch nur einen Zeiger auf das Ende der Liste habe?
Oder habe ich einen Denkfehler bei meinem Vorgehen:
Liste leer? → Eintragen und sofort das Lock erlangen
Liste nicht leer? → Eintragen und warten, bis alle Vorgänger “fertig” werden, sodass man selbst das Lock nehmen kann. Nur wie komme ich an diese Vorgänger?
unlock():
“[…] versucht er atomar, das Ende der Warteschlange auf null zu setzen.”
Warum tail auf null setzen? Es könnte doch einen Vorgänger geben, auf den tail stattdessen jetzt zeigen könnte.
Ruft ein Thread T lock() auf, trägt er sich atomar ans Ende der Warteschlange ein (verwenden Sie dazu getAndSet).
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicReference.html#getAndSet(V)
http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html
MCSLock.lock():
Wenn die Liste nicht leer ist und ein anderer Thread das Lock hält, wie finde ich ihn dann, wenn ich doch nur einen Zeiger auf das Ende der Liste habe?
Oder habe ich einen Denkfehler bei meinem Vorgehen:
Liste leer? → Eintragen und sofort das Lock erlangen
Liste nicht leer? → Eintragen und warten, bis alle Vorgänger „fertig“ werden, sodass man selbst das Lock nehmen kann. Nur wie komme ich an diese Vorgänger?
Du trägst dich ans Ende der Schlange ein. Deinen Thread geht es gar nichts an, welche Threads vor ihm noch alle das Lock bekommen. Fakt ist: Er kommt nach dem aktuell letzten dran. Irgendwann also wird der letzte Thread das Lock bekommen und wenn er es wieder hergibt, dann ist dein Thread dran. Wie viele davor noch kommen, ist irrelevant.
unlock():
„[…] versucht er atomar, das Ende der Warteschlange auf null zu setzen.“
Warum tail auf null setzen? Es könnte doch einen Vorgänger geben, auf den tail stattdessen jetzt zeigen könnte.
Ließ mal, was du da durch […] ersetzt hast. Dann siehst du nämlich, dass da steht, dass er erst prüfen soll, ob er der letzte ist. Also kann es da erst mal keinen geben. Und ließ den Satz danach, um zu erfahren, was zu tun ist, wenn sich parallel einer einträgt ;).