Universidad de Costa RicaEscuela de Ciencias de la Computación e InformáticaCI-0122 Sistemas OperativosTemas |
![]() |
CI0122 / Temas revisados / Semana-06 / Java / DP |
/**
*
* This solution is a Silberschatz Operating System book adaptation
* Simulates a "monitor" using a Java class
* use a lock to control access to monitor methods
*
**/
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
/**
* Emulates the Dining Philosophers problem
*/
public class DiningPh {
final ReentrantLock monitor = new ReentrantLock(); // Restricts access to each public method in this class (monitor)
final Condition[] self = new Condition[5]; // Access control to chopstick
public enum State { Thinking, Hungry, Eating } // Philosopher's states
private State[] state; // Each of the philosophers state
/**
* Initializes all monitor variables
**/
public DiningPh() {
state = new State[ 5 ];
for ( int person = 0; person < 5; person++ ) {
state[ person ] = State.Thinking;
self[ person ] = monitor.newCondition(); // Creates a new condition variable associated with monitor lock
}
}
/*
* Check if a philosopher can pick up his two chopsticks, if not the thread will wait
* @param who philosopher number trying to pickup chopsticks
*/
public void pickup( int who ) {
state[ who ] = State.Hungry;
monitor.lock();
try {
printstr( who, "will try to pickup sticks" );
test( who );
if ( state[ who ] == State.Hungry ) {
printstr( who, "\tsticks are busy, will wait for them " );
self[ who ].await(); // Chopsticks are busy, thread must wait
}
} catch ( InterruptedException intException ) {
} finally {
monitor.unlock();
}
printstr( who, "will start eating" );
}
/*
* When a philosopher ends eating, he will return chopsticks
* With this two freed chopsticks, the thread need to check if one of their neighbors are waiting for one
* and awake it using the test method
* @param who philosopher number who returns its chopsticks
*/
public void putdown( int who ) {
monitor.lock();
try {
printstr( who, "end eating, will putdown sticks" );
state[ who ] = State.Thinking; // Change state to thinking
test( (who + 4) % 5 ); // Check for right neighbor
test( (who + 1) % 5 ); // Check for left heighbor
} finally {
monitor.unlock();
}
}
/*
* Check if a philosopher can eat, verify if both chopsticks are free and self state to "Hungry"
* @param who philosopher number checking it he can eat
*/
private void test( int who ) {
if ( ( state[ (who + 4) % 5 ] != State.Eating ) &&
( state[ who ] == State.Hungry ) &&
( state[ (who + 1) % 5] != State.Eating ) ) {
state[ who ] = State.Eating;
printstr( who, "will signal condition" );
self[ who ].signal();
}
}
/*
* Print each person status, called from within a thread
* @param who philosopher number who want to print
*/
public void print( int who ) {
for ( int person = 0; person < 5; person++ ) {
System.out.printf( "(%d) Philosopher %d is %s \n", who, person + 1, (state[person]==State.Hungry)?"Hungry":(state[person]==State.Thinking)?"Thinking":"Eating");
}
}
/*
*
*/
public void printstr( int who, String s ) {
int person = who + 1;
System.out.println( "Philosopher " + person + ", " + s );
}
}