// 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(); } } }