Skip to content

Instantly share code, notes, and snippets.

@smartkiwi
Created April 29, 2013 22:55
Show Gist options
  • Save smartkiwi/5485472 to your computer and use it in GitHub Desktop.
Save smartkiwi/5485472 to your computer and use it in GitHub Desktop.
PA2 Java
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created with IntelliJ IDEA.
* User: vvlad
* Date: 4/2/13
* Time: 3:21 PM
* To change this template use File | Settings | File Templates.
*/
class Chopstick
{
ReentrantLock lock = new ReentrantLock();
public Chopstick()
{
}
boolean take()
{
if (!this.lock.isLocked()) {
this.lock.lock();
return true;
}
return false;
}
void put()
{
this.lock.unlock();
}
}
class Philosopher implements Runnable
{
private final int maxPause = 100;
private int maxEatTime = 5;
int number;
Chopstick left, right;
int eattime = 1;
public Philosopher(int i,Chopstick left, Chopstick right)
{
this.number = ++i;
this.left = left;
this.right = right;
}
public void eat()
{
boolean hasleft = _takeLeft();
boolean hasright = _takeRight();
if (hasright && hasleft)
{
System.out.println("Philosopher " + number + " eats: "+eattime);
}
if (hasright)
_putRight();
if (hasleft)
_putLeft();
if (hasright && hasleft)
{
eattime++;
}
}
private boolean _takeLeft()
{
boolean hasleft = false;
if (left.take())
{
System.out.println("Philosopher "+number+" picks up left chopstick: "+eattime);
hasleft = true;
pause();
}
return hasleft;
}
private boolean _takeRight()
{
boolean hasright = false;
if (right.take())
{
System.out.println("Philosopher "+number+" picks up right chopstick: "+eattime);
hasright = true;
pause();
} else {
System.out.println("Philosopher "+number+" failed to pick right chopstick - it is busy: "+eattime);
}
return hasright;
}
private void _putLeft() {
System.out.println("Philosopher "+number+" puts left chopstick: "+eattime);
left.put();
pause();
}
private void _putRight() {
System.out.println("Philosopher "+number+" puts right chopstick: "+eattime );
right.put();
pause();
}
/**
* Make random pause - to decrease contention cases and reduce number of retries
*/
public void pause() {
try {
int pause = (int) (Math.random() * maxPause);
Thread.sleep(pause);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (eattime<= maxEatTime)
eat();
}
}
public class DiningPhilosophers {
private final int size = 3;
List<Chopstick> chopsticks = new ArrayList<Chopstick>();
List<Thread> philosophers = new ArrayList<Thread>();
void run()
{
for (int i=0;i< size;i++) {
chopsticks.add(new Chopstick());
}
for (int i=0;i< size;i++)
{
int left = i;
int right = i<size-1 ? i+1 : 0;
Thread t = new Thread(new Philosopher(i,chopsticks.get(left),chopsticks.get(right)));
t.start();
philosophers.add(t);
}
for (Thread t : philosophers) {
try {
t.join(1000000);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
public static void main(String[] args){
System.out.println("Dinner is starting!");
DiningPhilosophers dt = new DiningPhilosophers();
dt.run();
System.out.println("Dinner is over!");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment