import java.util.*;
public class Philosopher implements Runnable {
private int id; private DiningRoom diningRoom;
public Philosopher(int i, DiningRoom dr) { id=i; diningRoom=dr; } public void think() { System.out.println(id+": thinking.."); try { Thread.sleep(50+(int)(Math.random()*800.0)); } catch (Exception e) { } } public void run() { for (int i=0; i<3; i++) { think(); diningRoom.dine(id); } } public static void main(String args[]) { DiningRoom dr=new DiningRoom(); Philosopher p[]={ new Philosopher(0,dr), new Philosopher(1,dr), new Philosopher(2,dr), new Philosopher(3,dr), new Philosopher(4,dr) }; for (int i=0; i
class DiningRoom {
private final static int THINKING=0; private final static int HUNGRY=1; private final static int EATING=2;
private int[] state = { THINKING,THINKING,THINKING,THINKING,THINKING };
private void eat(int p) { System.out.println(p+": eating.."); try { Thread.sleep(50+(int)(Math.random()*800.0)); } catch (Exception e) { } } public void dine(int p) { grabForks(p); eat(p); releaseForks(p);
} private synchronized void grabForks(int p) { state[p]=HUNGRY; System.out.println(p+": waiting & hungry.."); test(p); while ( state[p] != EATING ) try { wait(); } catch(Exception e) {} } private synchronized void releaseForks(int p) { state[p]=THINKING; test((p+4)%5); test((p+1)%5); } private void test(int p) { if ( state[p] == HUNGRY && state[(p+1)%5] != EATING && state[(p+4)%5] != EATING ) { state[p]=EATING; notifyAll(); } } }
Segundo class Semaphore extends Object { private int count;
public Semaphore(int startingCount) { count = startingCount; }
public void down(){ synchronized (this) { while (count <= 0) { // We must wait try { wait(); } catch (InterruptedException ex) { // I was interupted, continue onwards } } // We can decrement the count count--; } }
public void up(){ synchronized (this) { count++;
// notify a waiting thread to wakeup if (count == 1 ) { notify(); } } } }
Tercero // Philosopher.java
import Semaphore;
public class Philosopher extends Thread { // Shared by all Philosophers public final static int N = 5;
// Number of philosophers
public final static int THINKING = 0; thinking public final static int HUNGRY = 1; public final static int EATING = 2;
// Philosopher is // Philosopher is hungry // Philosopher is eating
private static int state[] = new int[N]; everyones state
// Array to keep track of
private static Semaphore mutex = new Semaphore(1); exclusion for
// Mutual // critical
regions private static Semaphore s[] = new Semaphore[N]; Philosopher
// Instance variable public int myNumber; public int myLeft; public int myRight; neighbor
public Philosopher(int i) { myNumber = i; myLeft = (i+N-1) % N; myRight = (i+1) % N; }
public void run() { while(true){
// One for each
// Which philosopher am I // Number of my left neighbor // Number of my right
// Make a philosopher // Compute the left neighbor // Compute the right neighbor
// And away we go
think(); take_forks(); eat(); put_forks();
// // // //
Philosopher is thinking Acquire two forks or block Yum-yum, spahgetti Put both forks back on the
table } }
public void take_forks(){ mutex.down(); state[myNumber] = HUNGRY; hungry test(myNumber); mutex.up(); s[myNumber].down(); acquired }
public void put_forks(){ mutex.down(); state[myNumber] = THINKING; eating test(myLeft); now eat test(myRight); now eat mutex.up(); }
public void test(int k){ int onLeft = (k+N-1) % N; int onRight = (k+1) % N; if( state[k] == HUNGRY && state[onLeft] != EATING && state[onRight] != EATING ) { // Grab those forks state[k] = EATING; s[k].up(); }
// Take the forks I need // Enter critical region // Record the fact that I am // Try to acquire two forks // Leave critical region // Block if forks were not
// Enter critical region // Philosopher has finished // See if left neighbor can // See if right neighbor can // Leave critical region
// // // //
Test philosopher k, from 0 to N-1 K's left neighbor K's right neighbor
}
public void think(){ System.out.println("Philosopher " + myNumber + " is thinking"); try { sleep(1000); } catch (InterruptedException ex){ } }
public void eat(){ System.out.println("Philosopher " + myNumber + " is eating"); try {
sleep(5000); } catch (InterruptedException ex){ } }
public static void main(String args[]) {
Philosopher p[] = new Philosopher[N];
for(int i=0; i
// Start the threads running p[i].start(); } } }