parallele-programmierung/u05-3/DiningPhilosophersWithForkA...

73 lines
1.9 KiB
Java

// import java.util.concurrent.Semaphore;
class DiningPhilosophersWithForkAccessSema extends Thread {
private static final int N = 5; // Anzahl Philosophen
static private Semaphore[] forks;
static private Semaphore accessForks = new Semaphore(N-1);
// At most N-1 philosophers must try to grab a fork
// Precisely, at most N2: Performance is even better then.
private int i; // Number of this philosopher
private int nEatings = 0; // how often did this philosopher eat?
public DiningPhilosophersWithForkAccessSema(int i) {
this.i = i;
}
private void takeForks() throws InterruptedException {
accessForks.acquire();
forks[i].acquire();
forks[(i+1)%N].acquire();
}
private void putForks() {
forks[i].release();
forks[(i+1)%N].release();
accessForks.release();
}
public void run() {
while (!isInterrupted()) {
try {
think();
takeForks();
eat();
putForks();
} catch (InterruptedException e) {
break;
}
}
System.out.println("Philosopher " + i + " has eaten " + nEatings + "times.");
}
private void eat() throws InterruptedException {
nEatings++;
System.out.println("Philosopher " + i + " eats for the " + nEatings + "th time.");
Thread.sleep((long) (Math.random() * 10));
}
private void think() throws InterruptedException {
System.out.println("Philosoph " + i + " thinks.");
Thread.sleep((long) (Math.random() * 10));
}
public static void main(String[] args) throws InterruptedException {
forks = new Semaphore[N];
for (int i = 0; i < N; i++) {
forks[i] = new Semaphore(1);
}
DiningPhilosophersWithForkAccessSema[] philosophers = new DiningPhilosophersWithForkAccessSema[N];
for (int i = 0; i < N; i++) {
philosophers[i] = new DiningPhilosophersWithForkAccessSema(i);
philosophers[i].start();
}
Thread.sleep(5_000); // Let philosophers run for 5 seconds
for (Thread t: philosophers) {
t.interrupt();
}
}
}