// Loosely based on Arnold, Gosling, Holmes p. 252 class PhilosopherThread implements Runnable { /*@non_null@*/ private Philosopher philosopher; public PhilosopherThread (/*@non_null@*/ Philosopher p) { philosopher = p; } public void run () { philosopher.philosophize (); } } public class Philosopher { private Philosopher colleague; private String name; private String quote; public Philosopher (String name, String quote) { this.name = name; this.quote = quote; } public synchronized void setColleague (Philosopher p) { colleague = p; } public void philosophize () { Object lock1, lock2; if (colleague != null) { // Need a colleague to start and argument. // Always grab the lock for whichever name is alphabetically first if (name.compareTo (colleague.name) < 0) { lock1 = this; lock2 = colleague; } else { lock1 = colleague; lock2 = this; } synchronized (lock1) { synchronized (lock2) { System.err.println (name + "[Thread " + Thread.currentThread().getName () + "] says " + quote); colleague.argue (); } } } } public synchronized void argue () { System.err.println (name + "[Thread " + Thread.currentThread().getName () + "] argues: No! " + quote); } public static void main (String [] args) { Philosopher descartes = new Philosopher ("Descartes", "I think, therefore I am."); Philosopher plato = new Philosopher ("Plato", "The life which is unexamined is not worth living."); descartes.setColleague (plato); plato.setColleague (descartes); Thread dthread = new Thread (new PhilosopherThread (descartes)); Thread pthread = new Thread (new PhilosopherThread (plato)); dthread.start (); pthread.start (); } }