Hi 
Eine Frage zu einem Programm, das ich aus einem Buch habe (Parallele und verteilte Anwendungen in Java, Hanser-Verlag, ISBN 978-3-446-43888-0). Listing 3.9:
In der Methode putFork gibt es ein notifyAll (Zeile 45). Hierzu ein Zitat aus dem Buch:
Ich denke mir jedoch, dass ein notify reicht. Darum habe ich aus dem notifyAll ein notify gemacht und NUMBER (Zeile 100) auf 3 reduziert. Selbst in diesem Fall scheint das Programm zu funktionieren.
Was sagt ihr dazu? Ist das notifyAll wirklich nötig, oder verstehe ich den Buchautor nur falsch?
P. S. falls jemand dieses Philosopen-Problem noch nicht kennt: 5 Philosophen sitzen zum Essen und Philosophieren an einem gemeinsamen Tisch. Jeder Philosoph hat einen Teller. Zwischen den Tellern liegen die Gabeln - zu 5 Tellern gibt es 5 Gabeln. Zum Essen benötigt ein Philosoph die Gabeln rechts UND links von seinem Teller. Isst der linke oder rechte Sitznachbar, kann der Philosoph nicht essen, weil ihm dazu nicht beide Gabeln zur Verfügung stehen.
Eine Frage zu einem Programm, das ich aus einem Buch habe (Parallele und verteilte Anwendungen in Java, Hanser-Verlag, ISBN 978-3-446-43888-0). Listing 3.9:
Java:
class Table
{
private boolean[] forkUsed;
private int left(int i)
{
return i;
}
private int right(int i)
{
if(i + 1 < forkUsed.length)
return i + 1;
else
return 0;
}
public Table(int number)
{
forkUsed = new boolean[number];
for(int i = 0; i < forkUsed.length; i++)
forkUsed[i] = false;
}
public synchronized void takeFork(int number)
{
while(forkUsed[left(number)] || forkUsed[right(number)])
{
try
{
wait();
}
catch(InterruptedException e)
{
}
}
forkUsed[left(number)] = true;
forkUsed[right(number)] = true;
}
public synchronized void putFork(int number)
{
forkUsed[left(number)] = false;
forkUsed[right(number)] = false;
notifyAll();
}
}
class Philosopher extends Thread
{
private Table table;
private int number;
public Philosopher(Table table, int number)
{
this.table = table;
this.number = number;
start();
}
public void run()
{
while(true)
{
think(number);
table.takeFork(number);
eat(number);
table.putFork(number);
}
}
private void think(int number)
{
System.out.println("Philosoph " + number + " denkt.");
try
{
sleep((int) (Math.random() * 20000));
}
catch(InterruptedException e)
{
}
}
private void eat(int number)
{
System.out.println("Philosoph " + number + " fängt zu essen an.");
try
{
sleep((int) (Math.random() * 20000));
}
catch(InterruptedException e)
{
}
System.out.println("Philosoph " + number + " hört auf zu essen.");
}
}
public class Philosophers
{
private static final int NUMBER = 5;
public static void main(String[] args)
{
Table table = new Table(NUMBER);
for(int i = 0; i < NUMBER; i++)
new Philosopher(table, i);
}
}
Das hört sich für mich so an, als ob ein notify nicht reichen würde, weil dann die Nachbarn nie essen könnten.Damit kann eventuell der linke oder rechte oder beide Nachbarn essen. Aus diesem Grund ist notifyAll statt notify nötig. Ein weiterer Grund für notifyAll ist, dass die Wartebedingung auch wieder parametrisiert ist, so dass es mehrere Wartebedingungen gibt.
Ich denke mir jedoch, dass ein notify reicht. Darum habe ich aus dem notifyAll ein notify gemacht und NUMBER (Zeile 100) auf 3 reduziert. Selbst in diesem Fall scheint das Programm zu funktionieren.
Was sagt ihr dazu? Ist das notifyAll wirklich nötig, oder verstehe ich den Buchautor nur falsch?
P. S. falls jemand dieses Philosopen-Problem noch nicht kennt: 5 Philosophen sitzen zum Essen und Philosophieren an einem gemeinsamen Tisch. Jeder Philosoph hat einen Teller. Zwischen den Tellern liegen die Gabeln - zu 5 Tellern gibt es 5 Gabeln. Zum Essen benötigt ein Philosoph die Gabeln rechts UND links von seinem Teller. Isst der linke oder rechte Sitznachbar, kann der Philosoph nicht essen, weil ihm dazu nicht beide Gabeln zur Verfügung stehen.
Zuletzt bearbeitet: