Skip to content

Instantly share code, notes, and snippets.

@antgustech
Created December 9, 2016 15:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antgustech/c34b8931e5675c1fc3d7e6f7be6f84b0 to your computer and use it in GitHub Desktop.
Save antgustech/c34b8931e5675c1fc3d7e6f7be6f84b0 to your computer and use it in GitHub Desktop.
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