Eating philosofer example
package main; | |
import java.util.concurrent.Semaphore; | |
/** | |
* Thread representing a philosofer. | |
* | |
* @author Anton Gustafsson | |
* | |
*/ | |
public class Philosofer implements Runnable { | |
private byte i; | |
private Semaphore mutex; | |
private Semaphore forks; | |
private final short THINKING = 0; | |
private final short HUNGRY = 1; | |
private final short EATING = 2; | |
private final byte[] states; | |
/** | |
* Initializes variables. | |
* | |
* @param states - byte array determing which state this philosofer is in. | |
* @param i - the name of this philosofer. | |
* @param mutex - a binary semaphore acting mutex.. | |
* @param forks - a semaphore lock which has 4 forks. | |
*/ | |
public Philosofer(byte[] states, byte i, Semaphore mutex, Semaphore forks) { | |
this.states = states; | |
this.i = i; | |
this.mutex = mutex; | |
this.forks = forks; | |
states[i] = THINKING; | |
} | |
/** | |
* Lifecycle of the philosofer. | |
*/ | |
@Override | |
public void run() { | |
while (true) { | |
prt(); | |
think(); | |
prt(); | |
takeForks(); | |
prt(); | |
eat(); | |
prt(); | |
putForks(); | |
prt(); | |
} | |
} | |
/** | |
* Philosofer is thinking for a random amount of time. | |
*/ | |
private void think() { | |
try { | |
Thread.sleep((int) (Math.random() * 1000)); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
/** | |
* Philosofer is eating for random amount of time. | |
* Just calls think as they essential do the same thing. | |
*/ | |
private void eat() { | |
think(); | |
} | |
/** | |
* Method that takes the forks from the table. First it locks | |
* with a mutex then it changes state to hungry and check if it's | |
* neighbors are already eating. | |
*/ | |
private void takeForks() { | |
try { | |
System.out.println("MUTEX LOCK"); | |
mutex.acquire(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
states[i] = HUNGRY; | |
prt(); | |
checkNeighbors(i); | |
mutex.release(); | |
System.out.println("MUTEX UNLOCK"); | |
} | |
/** | |
* Method that put down 2 forks to the table. Then it locks the mutex, changes it | |
* state to thinking and then checks if it's neignoring philosofers | |
* want to eat. | |
* | |
*/ | |
private void putForks() { | |
forks.release(2); | |
try { | |
mutex.acquire(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
states[i] = THINKING; | |
checkNeighbors(left(i)); | |
checkNeighbors(right(i)); | |
mutex.release(); | |
} | |
/** | |
* Checks if any of the neighbors are eating. | |
* | |
* @param i | |
*/ | |
private void checkNeighbors(short i) { | |
if (states[i] == HUNGRY && left(i) != EATING && right(i) != EATING) { | |
states[i] = EATING; | |
try { | |
forks.acquire(2); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
/** | |
* Checks if we are out of bounds to the left. if so, return the last index. | |
* | |
* @param i | |
* @return | |
*/ | |
private short left(short i) { | |
if (i - 1 < 0) { | |
return states[4]; | |
} | |
return states[i - 1]; | |
} | |
/** | |
* Checks out of bounds to the right. If so, return the first element. | |
* | |
* @param i | |
* @return | |
*/ | |
private short right(short i) { | |
if (i + 1 > 4) { | |
return states[0]; | |
} | |
return states[i + 1]; | |
} | |
private void prt() { | |
short s = states[i]; | |
if (s == HUNGRY) { | |
System.out.println("Philosofer " + i + " Is " + " (HUNGRY)"); | |
} else if (s == THINKING) { | |
System.out.println("Philosofer " + i + " Is " + " (THINKING)"); | |
} else if (s == EATING) { | |
System.out.println("Philosofer " + i + " Is " + " (EATING)"); | |
} | |
} | |
} |
package main; | |
import java.util.concurrent.Semaphore; | |
/** | |
* This class starts the program, creates threads and call their start method. | |
* @author Anton Gustafsson | |
* | |
*/ | |
public class Start { | |
/** | |
* Creates and starts new threads. One for each Philosofer. | |
* The state is used to keep track of what each philosofer is doing | |
* and the semaphores are of course there to represent forks and mutex. | |
*/ | |
public static void main(String[] args) { | |
byte[] states = new byte[5]; | |
Semaphore mutex = new Semaphore(1); | |
Semaphore forks = new Semaphore(4); | |
Thread p0 = new Thread(new Philosofer(states,(byte) 0, mutex, forks )); | |
Thread p1 = new Thread(new Philosofer(states,(byte) 1, mutex, forks )); | |
Thread p2 = new Thread(new Philosofer(states,(byte) 2, mutex, forks )); | |
Thread p3 = new Thread(new Philosofer(states,(byte) 3, mutex, forks )); | |
Thread p4 = new Thread(new Philosofer(states,(byte) 4, mutex, forks )); | |
p0.start(); | |
p1.start(); | |
p2.start(); | |
p3.start(); | |
p4.start(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment