import java.util.Random; import java.util.concurrent.Semaphore; /** * Solves the dining philosophers problem * This version uses a semaphore to control access to * each fork. * * @author Scot Drysdale */ public class PhilosopherSemaphore extends Thread { private int myNum; // Number of this philosopher private static Semaphore [] forks; private Random generator; private static final int EAT_TIME = 1000; private static final int THINK_TIME = 1000; private static final int NUM_MEALS = 10; private static final int NUM_PHILOSOPHERS = 6; public PhilosopherSemaphore(int philNum) { myNum = philNum; generator = new Random(); } /** * Eat using semaphores to control the forks This version can (and probably * will) deadlock */ public void starve(int meal) throws InterruptedException { System.out.println("Philosopher " + myNum + " tries to pick up fork " + myNum); forks[myNum].acquire(); System.out.println("Philosopher " + myNum + " has fork " + myNum + " and tries to pick up fork " + ((myNum + 1) % NUM_PHILOSOPHERS)); sleep(10); forks[(myNum + 1) % NUM_PHILOSOPHERS].acquire(); System.out.println("Philosopher " + myNum + " eats meal " + meal); sleep(EAT_TIME + generator.nextInt(EAT_TIME)); System.out.println("Philosopher " + myNum + " puts down forks and thinks"); forks[myNum].release();; forks[(myNum + 1) % NUM_PHILOSOPHERS].release(); sleep(THINK_TIME + generator.nextInt(THINK_TIME)); } public void run() { try { for (int meal = 1; meal <= NUM_MEALS; meal++) starve(meal); } catch (InterruptedException e) { } } public static void main(String[] args) { forks = new Semaphore[NUM_PHILOSOPHERS]; for(int i = 0; i < NUM_PHILOSOPHERS; i++) forks[i] = new Semaphore(1, true); for (int num = 0; num < NUM_PHILOSOPHERS; num++) { PhilosopherSemaphore phil = new PhilosopherSemaphore(num); phil.start(); } } /** * Eat using semaphores to control the forks This version cannot deadlock */ public void eat(int meal) throws InterruptedException { if (myNum % 2 == 0) { System.out.println("Philosopher " + myNum + " tries to pick up fork " + myNum); forks[myNum].acquire();; System.out.println("Philosopher " + myNum + " has fork " + myNum + " and tries to pick up fork " + ((myNum + 1) % NUM_PHILOSOPHERS)); sleep(10); forks[(myNum + 1) % NUM_PHILOSOPHERS].acquire();; System.out.println("Philosopher " + myNum + " eats meal " + meal); } else { System.out.println("Philosopher " + myNum + " tries to pick up fork " + ((myNum + 1) % NUM_PHILOSOPHERS)); forks[((myNum + 1) % NUM_PHILOSOPHERS)].acquire(); System.out.println("Philosopher " + myNum + " has fork " + ((myNum + 1) % NUM_PHILOSOPHERS) + " and tries to pick up fork " + myNum); sleep(10); forks[myNum].acquire();; System.out.println("Philosopher " + myNum + " eats meal " + meal); } sleep(EAT_TIME + generator.nextInt(EAT_TIME)); System.out.println("Philosopher " + myNum + " puts down forks and thinks"); forks[myNum].release();; forks[(myNum + 1) % NUM_PHILOSOPHERS].release();; sleep(THINK_TIME + generator.nextInt(THINK_TIME)); } }