Java tutorial
// : c13:DiningPhilosophers.java // Demonstrates how deadlock can be hidden in a program. // {Args: 5 0 deadlock 4} // From 'Thinking in Java, 3rd ed.' (c) Bruce Eckel 2002 // www.BruceEckel.com. See copyright notice in CopyRight.txt. import java.util.Random; import java.util.Timer; import java.util.TimerTask; class Chopstick { private static int counter = 0; private int number = counter++; public String toString() { return "Chopstick " + number; } } class Philosopher extends Thread { private static Random rand = new Random(); private static int counter = 0; private int number = counter++; private Chopstick leftChopstick; private Chopstick rightChopstick; static int ponder = 0; // Package access public Philosopher(Chopstick left, Chopstick right) { leftChopstick = left; rightChopstick = right; start(); } public void think() { System.out.println(this + " thinking"); if (ponder > 0) try { sleep(rand.nextInt(ponder)); } catch (InterruptedException e) { throw new RuntimeException(e); } } public void eat() { synchronized (leftChopstick) { System.out.println(this + " has " + this.leftChopstick + " Waiting for " + this.rightChopstick); synchronized (rightChopstick) { System.out.println(this + " eating"); } } } public String toString() { return "Philosopher " + number; } public void run() { while (true) { think(); eat(); } } } public class DiningPhilosophers { public static void main(String[] args) { if (args.length < 3) { System.err.println( "usage:\n" + "java DiningPhilosophers numberOfPhilosophers " + "ponderFactor deadlock timeout\n" + "A nonzero ponderFactor will generate a random " + "sleep time during think().\n" + "If deadlock is not the string " + "'deadlock', the program will not deadlock.\n" + "A nonzero timeout will stop the program after " + "that number of seconds."); System.exit(1); } Philosopher[] philosopher = new Philosopher[Integer.parseInt(args[0])]; Philosopher.ponder = Integer.parseInt(args[1]); Chopstick left = new Chopstick(), right = new Chopstick(), first = left; int i = 0; while (i < philosopher.length - 1) { philosopher[i++] = new Philosopher(left, right); left = right; right = new Chopstick(); } if (args[2].equals("deadlock")) philosopher[i] = new Philosopher(left, first); else // Swapping values prevents deadlock: philosopher[i] = new Philosopher(first, left); // Optionally break out of program: if (args.length >= 4) { int delay = Integer.parseInt(args[3]); if (delay != 0) new Timeout(delay * 1000, "Timed out"); } } } ///:~ class Timeout extends Timer { public Timeout(int delay, final String msg) { super(true); // Daemon thread schedule(new TimerTask() { public void run() { System.out.println(msg); System.exit(0); } }, delay); } } ///:~