The Terminator
Cadet 4th Year
- Registriert
- Dez. 2010
- Beiträge
- 73
Hallo Leute!
Ich hoffe, ihr könnt mir hier weiterhelfen, ich sitze schon eine ganze Weile ohne weitergekommen zu sein.
Das Grundproblem: Wir sollen die Dining Philosophers in eine bereits vorhandene Swing-Applikation implementieren, wobei nur ein paar Codestellen/Methoden auszufüllen sind.
Das Ziel/Deadlock-Strategien ist, dass drei Teile erreicht werden (ich zitier aus der Angabe):
1. Nur Synchronisation, keine Deadlock Vermeidung
2. Deadlock-Vermeidung durch unterlassen von Hold-and-Wait
3. Deadlock-Beseitigung
Implementieren soll man dies mittels Semaphoren (oder auch Lock).
So weit so gut. Ich habe auch nun alles gemacht, hier der Code meiner Methoden:
Klasse Philosophers (Unterklasse von Thread, die einzelnen Schritte, die laut Angabe durchgeführt werden müssen, sind mit 1. bis 7. kommentiert):
Klasse Chopstick:
Das vorgegebene Hauptprogramm macht im Wesentlichen die grafische Darstellung. Als Initialisierung werden stets fünf Chopsticks und fünf neue Philosophers erzeugt und gestartet. Folgende Operationen sind in der GUI verfügbar:
> Swing-Radio-Box: Umschalten der drei Strategien mit anschließender Betätigung des Buttons (dabei wird eine komplette Neuinitialisierung der Chopsticks und Philosophers veranlasst)
> Anzeige des Tisches (mit Chopsticks und Philosophers)
> Anzeige einer Text-Infobox (da kommen die Nachrichten der Philosophers-Klasse mittels addInfoText(String) hinein)
Und nun mein Problem: Es funktioniert eigentlich alles wunderbar, außer wenn ich im laufenden Programm zwischen den Strategien wechsle. Dann kann (muss aber auch nicht!!!) z.B. folgendes passieren:
> Starte Programm mit Strategie 1 (nichts tun, muss Deadlock produzieren)
> Wechsle mitten drin auf Strategie 2 (Prevention)
> Nach einer kurzen Zeit wechsle wieder auf Strategie 1
> Jetzt kommt's: Es wird ein Deadlock produziert (Grafik --> alle Philosophers warten mit je einem Chopstick) ABER DENNOCH erscheinen in der Text-Infobox eine gewisse Zeit lang Nachrichten, dass Chopsticks genommen und wieder frei gegeben werden OBWOHL eigentlich eine Deadlock vorherrscht. Wie gerade gesagt, nach einer gewissen Zeit passt dann alles wieder.
Übrigens passiert das auch, wenn ich Strategie 1 laufen lasse und auf Re-Start (damit werden eben die Strategien gewechselt, außer man hat dieselbe eingestellt, dann wird die natürlich nur neu gestartet) drücke, BEVOR ein Deadlock eingetreten ist.
Ich hoffe, dass mein Problem so halbwegs verständlich ist.
Ich weiß echt nicht, woran das liegen könnte. Entweder bin ich einfach zu dumm oder übersehe grad irgendetwas.
Im Anhang lade ich die App (als gezippte .jar, da CB ohne zip das leider verhindert) hoch, den gesamten Code will ich eher nicht uploaden, da er ja größtenteils nicht von mir stammt. Wenn noch irgendetwas unklar ist oder jemand mehr Infos benötigt, dann werde ich mich natürlich bemühen, alles zu beantworten/ergänzen.
Vielen Dank schon im Voraus
LG
P.S.: weiß leider nicht, wie man den Code einklappbar macht (damit er nicht soviel Platz verbraucht)
Ich hoffe, ihr könnt mir hier weiterhelfen, ich sitze schon eine ganze Weile ohne weitergekommen zu sein.
Das Grundproblem: Wir sollen die Dining Philosophers in eine bereits vorhandene Swing-Applikation implementieren, wobei nur ein paar Codestellen/Methoden auszufüllen sind.
Das Ziel/Deadlock-Strategien ist, dass drei Teile erreicht werden (ich zitier aus der Angabe):
1. Nur Synchronisation, keine Deadlock Vermeidung
2. Deadlock-Vermeidung durch unterlassen von Hold-and-Wait
3. Deadlock-Beseitigung
Implementieren soll man dies mittels Semaphoren (oder auch Lock).
So weit so gut. Ich habe auch nun alles gemacht, hier der Code meiner Methoden:
Klasse Philosophers (Unterklasse von Thread, die einzelnen Schritte, die laut Angabe durchgeführt werden müssen, sind mit 1. bis 7. kommentiert):
Code:
public void run()
{
while (true) { // just continue forever (= 7.)
try {
// 1. thinking
waiting = false;
delay();
// 2. waiting for left chopstick
addInfoText("waits for left chopstick to become available");
waiting = true;
// always (regardless of the currently active strategy) try to acquire the
// left chopstick (wait if it is currently held by another philosopher)
left.grab(this, false);
addInfoText("grabbed left chopstick"); // includes tableChanged
waiting = false;
// 3. thinking
delay();
// 4. waiting for right chopstick
addInfoText("waits for right chopstick to become available");
waiting = true;
// try to acquire the right chopstick; if the currently active strategy is
// "prevention", only try to acquire it if it is available (not held by
// another philosopher) - otherwise wait (which is enabled by "false")
if (!right.grab(this, table.isStrategyPrevent())) {
left.release(this); // release the currently hold left chopstick
addInfoText("could not get right chopstick - put back left chopstick");
continue; // start thinking again (includes delay)
}
addInfoText("grabbed right chopstick"); // includes tableChanged
waiting = false;
// 5. eating
eating = true;
delay();
eating = false;
// 6. putting back left and right chopstick
right.release(this);
addInfoText("released right chopstick"); // includes tableChanged
left.release(this);
addInfoText("released left chopstick"); // includes tableChanged
} catch (InterruptedException e) { // Zen-Master was active (strategy "detect/recover")
left.release(this); // forcefully release the currently hold left chopstick
addInfoText("was forced to put back left chopstick"); // includes tableChanged
waiting = false;
continue; // start thinking again (includes delay)
}
}
}
Klasse Chopstick:
Code:
private final Semaphore s = new Semaphore(1);
public boolean grab(Philosopher philo, boolean preventDeadlock) throws InterruptedException {
if (philo == null) {
throw new IllegalArgumentException("Philosopher must not be null.");
}
// only check the current owner of the chopstick if the currently active strategy
// is "prevention"; otherwise skip this part and continue at the standard procedure
if (preventDeadlock) {
if (owner != null) {
return false; // would have to wait for the chopstick
} // else continue below (standard procedure)
}
// standard procedure (regardless of currently active strategy)
s.acquire();
owner = philo;
return true;
}
public void release(Philosopher philo) {
if (philo == null || owner != philo) {
throw new IllegalArgumentException("Philosopher must not be null and must hold the chopstick.");
}
// make the chopstick available/"grab-able" again
owner = null;
s.release();
}
Das vorgegebene Hauptprogramm macht im Wesentlichen die grafische Darstellung. Als Initialisierung werden stets fünf Chopsticks und fünf neue Philosophers erzeugt und gestartet. Folgende Operationen sind in der GUI verfügbar:
> Swing-Radio-Box: Umschalten der drei Strategien mit anschließender Betätigung des Buttons (dabei wird eine komplette Neuinitialisierung der Chopsticks und Philosophers veranlasst)
> Anzeige des Tisches (mit Chopsticks und Philosophers)
> Anzeige einer Text-Infobox (da kommen die Nachrichten der Philosophers-Klasse mittels addInfoText(String) hinein)
Und nun mein Problem: Es funktioniert eigentlich alles wunderbar, außer wenn ich im laufenden Programm zwischen den Strategien wechsle. Dann kann (muss aber auch nicht!!!) z.B. folgendes passieren:
> Starte Programm mit Strategie 1 (nichts tun, muss Deadlock produzieren)
> Wechsle mitten drin auf Strategie 2 (Prevention)
> Nach einer kurzen Zeit wechsle wieder auf Strategie 1
> Jetzt kommt's: Es wird ein Deadlock produziert (Grafik --> alle Philosophers warten mit je einem Chopstick) ABER DENNOCH erscheinen in der Text-Infobox eine gewisse Zeit lang Nachrichten, dass Chopsticks genommen und wieder frei gegeben werden OBWOHL eigentlich eine Deadlock vorherrscht. Wie gerade gesagt, nach einer gewissen Zeit passt dann alles wieder.
Übrigens passiert das auch, wenn ich Strategie 1 laufen lasse und auf Re-Start (damit werden eben die Strategien gewechselt, außer man hat dieselbe eingestellt, dann wird die natürlich nur neu gestartet) drücke, BEVOR ein Deadlock eingetreten ist.
Ich hoffe, dass mein Problem so halbwegs verständlich ist.
Ich weiß echt nicht, woran das liegen könnte. Entweder bin ich einfach zu dumm oder übersehe grad irgendetwas.
Im Anhang lade ich die App (als gezippte .jar, da CB ohne zip das leider verhindert) hoch, den gesamten Code will ich eher nicht uploaden, da er ja größtenteils nicht von mir stammt. Wenn noch irgendetwas unklar ist oder jemand mehr Infos benötigt, dann werde ich mich natürlich bemühen, alles zu beantworten/ergänzen.
Vielen Dank schon im Voraus
LG
P.S.: weiß leider nicht, wie man den Code einklappbar macht (damit er nicht soviel Platz verbraucht)
Zuletzt bearbeitet: