Aufgabe 4.7

FactorySorting

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 4.7
Mir ist noch nicht so ganz klar, wie die Main-Methode der Aufgabe “mitbekommt”, dass Items auch tatsächlich sortiert wurden. Ich habe alle Methoden soweit implementiert, dass die Funktion eben bis zum Ende durchläuft und die Anzahl “gelieferter” Elemente mit der der “sortierten” Elemente vergleicht.

In PeriodicIncomingTask habe ich entsprechend den Items 3 Storages angelegt, auf die die Elemente auch korrekt verteilt werden (sukzessives Entfernen der Elemente liefert wieder die richtige Anzahl “gelieferter” Elemente). Allerdings werden diese Elemente dann wie gesagt nicht als “sortierte” Elemente gewertet.

Habe ich irgendwo übersehen, dass bestimmte Storages als Ziel für die Sortierung zu verwenden sind oder liegt der Fehler woanders in meiner Implementierung?

EDIT: Ich gehe davon aus, dass ich die in der Main-Methode als public verfügbaren Felder usw. auch in anderen Klassen verwenden darf? Damit wäre meine Frage dann nämlich geklärt.


Ja darfst du :wink:

1 Like

Teilaufgabe d)
Verstehe ich richtig, dass ein PeriodicIncomingTask initialisiert werden soll, dem die beiden in Sorter vorhandenen Objekte incoming und executor übergeben werden sollen, und anschließend dessen run-Methode ohne Verwendung eines weiteren eigenen ExecutorServices alle 100 Millisekunden aufgerufen werden soll?


Also entweder haben nur gefühlte 1% der PFP-Hörer diese Bonusaufgabe bearbeitet und dadurch ist bis jetzt (kurz vor der Abgabe heute um 15.00 Uhr) noch niemandem meine Problematik, die ich gleich erläutern werde, aufgefallen - oder ich irre mich einfach.
Ich erachte zweiteres als sehr wahrscheinlich, möchte aber trotzdem mal Folgendes anbringen:

Ich hab die Vermutung, dass der/die Aufgabensteller in der [m]Main[/m]-Klasse eine kleine Race Condition beim Beenden des Zulieferns übersehen hat/haben.
Nehmen wir an, dass die [m]DeliveryService[/m]-Threads gerade noch am Laufen sind und sich alle 3 am Anfang ihrer [m]while (Main.RUNNING.get())[/m] Schleife befinden.
Anschließend wird in der Main-Methode [m]Main.RUNNING.set(false)[/m] ausgeführt, was dazu führt, dass die while-Schleifen ein letztes Mal durchlaufen werden.
Falls jetzt allerdings im Folgenden die Berechnung der [m]numberOfDeliveredItems [/m]bereits gleich im Anschluss geschieht, wird ja eine falsche Anzahl an gelieferten Items ermittelt, da die [m]DeliveryService[/m]-[m]while[/m]-Schleifen ja noch einmal ein Item in das Storage packen und den [m]Counter [/m]inkrementieren, nachdem bereits gezählt wurde.
Bei mir tritt das (ziemlich häufig für einen Heisenbug) folgendermaßen auf und sieht dann ungefähr so aus:

Nach dem Einfügen von Ausgaben an den Stellen nach der Counter-Erhöhung, beim Erstellen der Sort-Tasks und bei der Ausführung dieser kam ich allerdings zu dem Schluss, dass alles normal funktioniert - das würde dann wie hier aussehen:

In diesem speziellen Fall haben es beispielsweise 2 Deliverer vor dem Negieren der [m]RUNNING[/m]-[m]while[/m]-Bedingung geschafft, in den Anfang ihrer Schleife zu gelangen. Ihre jeweils ersten Items ([m]item1 [/m]für Deliverer1 und [m]item2 [/m]für Deliverer2) sind jedoch erst in das Storage gelegt worden, nachdem bereits die [m]numberOfDeliveredItems [/m]in der [m]Main[/m]-Methode gezählt wurden.


Ich weiß nicht, ob ich etwas falsch verstanden habe, aber ich habe überhaupt keine [m]while (Main.RUNNING.get())[/m]-Schleife. Aber so ganz erschließt es sich mir ja noch nicht, was ich hier eigentlich tue, bzw. warum ich es tue.

[size=4]Hach, ich bin mal wieder so früh dran mit Bearbeiten dieser Aufgabe. :)[/size]


Keine Sorge - es geht hierbei nicht um eine Implementierung unsererseits, ich kritisiere ausschließlich den bereits gegebenen Code des/der Aufgabensteller. :wink:
Die while-Schleife befindet sich in der [m]DeliveryService [/m]Klasse, die ja bereits vorgegeben ist.


Ich sehe hier auch ne Racecondition aber in umgekehrter Richtung ;):
Number of delivered items (2) is not equal to number of sorted items (0) halte ich für möglich.

Eigentlich dürften die beiden Items nicht mehr sortiert werden, da vorher shutdown aufgerufen wird.

Kannst du mal deine abzugebenden Dateien und deine Main.java an pfp@i2.cs.fau.de schicken?


Könnte mir jemand nen Tipp geben wie ich bei der c) auf "den passenden Storage " zugreifen kann? Die Storages sollen wir nicht selbst erstellen, oder? Und bei der d) sollen wir da immer alle CHECKPERIOD oder wie im Komentar steht SorterIncomingCheckPeriod(main) wiederholen?


Schau dir mal die Felder in der Main an :wink:

Ja sollt ihr nicht selbst erstellen.

Verwende CHECKPERIOD .

1 Like

Soll die [m]PeriodicIncomingTask.run[/m]-Methode eigentlich in jedem Aufruf nur das erste Item aus der incoming-Storage holen oder alle darin befindlichen?


Bei mir wird nur eins rausgenommen in der run


Also in der Aufgabenstellung stand ja:

(Das „die“ ist wahrscheinlich nur ein kleiner Fehler. ;))
Daher hab ich eben erst [m]shutdown [/m]ausgeführt, sofern der Lagerplatz leer ist.
Und wenn ich diese ganzen [m]SortTask[/m]s noch vor dem [m]shutdown [/m]reinschiebe, dann werden die ja auch alle noch ausgeführt - [m]shutdown [/m]bedeutet ja nur, dass anschließend keine neuen Tasks mehr angenommen werden.
Zumindest hab ich die Aufgabenstellung so verstanden.

Aber ich finde ja, dass das nichts an der Tatsache ändert, dass [m]numberOfDeliveredItems [/m]sich je nach Ausgang der Race Condition einen anderen Wert hat.
Und egal auf was wir uns jetzt für eine Anzahl am Schluss sortierter Items einigen - wenn diese den richtigen Wert hat - und [m]numberOfDeliveredItems [/m]schwankt - kommt es in einem der Fälle eben zu der unberechtigt geworfenen Exception.

Das hab ich zwar zuerst verneint, allerdings ist mir vorhin genau das ebenfalls noch passiert. In diesem Fall geschieht das Anliefern weiterer Items (das letzte +1 in der while-Schleife, deren Bedingung schon falsch ist) erst, nachdem bereits die Sortierung aufgrund des leeren Lagerplatzes und des [m]shutdown[/m]-Flags durchgeführt und der [m]ExecutorService [/m]bereits zum Beenden aufgerufen wurde.

Aber wie bereits zuvor erwähnt würde sich dieses ganze Problem ja lösen lassen, wenn man auf die Deliverer-Threads wartet (evtl. Join?), bevor man das Zählen anfängt.

EDIT: Werd hier jez gleich nochn Teil meines Codes anhängen - Abgabefrist ist ja schon rum. :slight_smile:


Bitte gehe den Weg über die Mailing-Liste und veröffentliche deine Lösung hier nicht, da die Aufgaben dann in künftigen Semestern nicht mehr verwendet werden können.


Achja richtig, tschuldigung. :slight_smile:
Hab’s per Mail geschickt - ist zwar irgendwie blöd weils ja so kurz vor knapp ist, aber wenn mir das eher aufgefallen wäre hät’ ichs natürlich dann schonmal angebracht. :wink:
Wahrscheinlich ist auch nur bei mir einfach alles falsch. :stuck_out_tongue: