package examples; import java.awt.Color; import java.awt.Font; import java.awt.GridLayout; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.locks.ReentrantLock; import javax.swing.JFrame; import javax.swing.JProgressBar; import javax.swing.border.LineBorder; import static java.awt.Color.*; public class DiningPhilosopher4 extends JProgressBar implements Runnable { private static final long serialVersionUID = 1L; static enum State {WAIT, EAT, DONE, THINK}; static Color[] stateColors = {RED, GREEN, YELLOW, BLACK}; static LineBorder[] borders = new LineBorder[4]; static final int SATIATED = 100; static Random random = new Random(); static int numPhilosophers = 0; static List locks = new ArrayList(); static {for (int i = 0; i < stateColors.length; i++) borders[i] = new LineBorder(stateColors[i], 5); } int id; public DiningPhilosopher4() { super(0, SATIATED); setFont(new Font("helvetica", Font.BOLD, 18)); setStringPainted(true); id = getNextID(); setState(State.THINK); } static int getNextID() { locks.add(new ReentrantLock()); return numPhilosophers++; } public void run() { for (int i = 0; i < SATIATED; i++) { for (State s : State.values()) setState(s); } } void setState(State s) { setBorder(borders[s.ordinal()]); setString(s.toString()); switch (s) { case WAIT: if (id == numPhilosophers-1) { locks.get(0).lock(); rest(50); locks.get(id).lock(); } else { locks.get(id).lock(); rest(50); locks.get((id+1) % numPhilosophers).lock(); } break; case EAT: setValue(getValue()+1); rest(random.nextInt(500)); break; case DONE: locks.get(id).unlock(); locks.get((id+1) % numPhilosophers).unlock(); break; case THINK: rest(random.nextInt(500)); break; } } static void rest(int milliseconds) { try { Thread.sleep(milliseconds); } catch (InterruptedException ie) { // wake up } } public static void main(String[] args) { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setLayout(new GridLayout(0,1)); for (int i = 0; i < 5; i++) f.add(new DiningPhilosopher4()); f.setSize(300,200); f.setVisible(true); rest(1000); for (java.awt.Component c : f.getContentPane().getComponents()) { (new Thread((DiningPhilosopher4) c)).start(); } } }