Created
October 6, 2013 12:28
-
-
Save kedarmhaswade/6853466 to your computer and use it in GitHub Desktop.
First Implementation of the Dining Philosophers where they are deadlock prone. For instance, you could easily get into a situation where all philosophers hold left fork and are waiting to catch hold of right one => deadlock.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.concurrent.CountDownLatch; | |
import java.util.concurrent.atomic.AtomicLong; | |
public class DiningPhilosophers { | |
volatile static boolean done; | |
final private Integer[] chopsticks; | |
public DiningPhilosophers(int n) { | |
chopsticks = new Integer[n]; | |
for (int i = 0 ; i < n ; i++) | |
chopsticks[i] = i; | |
} | |
public DiningPhilosophers start() { | |
CountDownLatch startSignal = new CountDownLatch(1); | |
for (int i = 0 ; i < chopsticks.length ; i++) { | |
new Thread(new DiningPhilosopher(i, chopsticks, startSignal)).start(); | |
} | |
startSignal.countDown(); | |
return this; | |
} | |
public DiningPhilosophers run(long ms) { | |
try { | |
Thread.sleep(ms); | |
} catch(InterruptedException ie) { | |
System.out.println(Thread.currentThread().getName() + " was interrupted!"); | |
} | |
DiningPhilosophers.done = true; | |
return this; | |
} | |
public void report() { | |
} | |
public static void main(String[] args) throws Exception { | |
if (args.length != 2) { | |
System.out.println("java DiningPhilosophers <no-of-philosophers> <time-of-simulation-ms>"); | |
System.exit(1); | |
} | |
new DiningPhilosophers(Integer.valueOf(args[0])).start().run(Integer.valueOf(args[1])).report(); | |
} | |
} | |
class DiningPhilosopher implements Runnable { | |
private final int id; // id's start at 0 | |
private final Integer[] chopsticks; //individual elements are shared | |
private final CountDownLatch startSignal; | |
public DiningPhilosopher(int id, Integer[] chopsticks, CountDownLatch startSignal) { | |
if (id < 0 || chopsticks == null || id >= chopsticks.length) { | |
throw new IllegalArgumentException("Provide proper array and proper id for me -- dining philosopher"); | |
} | |
this.id = id; | |
this.chopsticks = chopsticks; | |
this.startSignal = startSignal; | |
} | |
public int leftChopstickIndex() { | |
return id; | |
} | |
public int rightChildIndex() { | |
return (id + 1) % chopsticks.length; | |
} | |
public void run() { | |
try { | |
startSignal.await(); //wait for the latch | |
} catch(InterruptedException ie) { | |
System.out.println(Thread.currentThread().getName() + " was interrupted"); | |
} | |
while(!DiningPhilosophers.done) { | |
//deadlock prone -- grab the chocksticks and well, eat! | |
synchronized(chopsticks[leftChopstickIndex()]) { | |
synchronized(chopsticks[rightChildIndex()]) { | |
eat(); | |
} | |
} | |
//release the chopsticks and well, think! | |
think(); | |
} | |
System.out.println("DP " + id + " ate for: " + EatingTime.get() + " ms"); | |
System.out.println("DP " + id + " thought for: " + ThinkingTime.get() + " ms"); | |
} | |
public void eat() { | |
long t1 = System.currentTimeMillis(); | |
for (int i = 2 ; i < 10_000 ; i++) { | |
ParallelizableComputations.isPrimeSlow(i); | |
} | |
//System.out.println("DP " + id + " done eating"); | |
EatingTime.set(EatingTime.get() + (System.currentTimeMillis() - t1)); | |
} | |
public void think() { | |
long t1 = System.currentTimeMillis(); | |
for (int i = 2 ; i < 20_000 ; i++) { | |
ParallelizableComputations.isPrimeSlow(i); | |
} | |
//System.out.println("DP " + id + " done thinking"); | |
ThinkingTime.set(ThinkingTime.get() + (System.currentTimeMillis() - t1)); | |
} | |
} | |
class EatingTime { | |
private static final AtomicLong total = new AtomicLong(0); | |
private static final ThreadLocal<Long> eatingTime = | |
new ThreadLocal<Long>() { | |
@Override public Long initialValue() { | |
//return total.getAndIncrement(); | |
return 0L; | |
} | |
@Override public void set(Long ms) { | |
total.set(ms); | |
} | |
@Override public Long get() { | |
return total.get(); | |
} | |
}; | |
public static long get() { | |
return eatingTime.get(); | |
} | |
public static void set(long ms) { | |
eatingTime.set(ms); | |
} | |
} | |
class ThinkingTime { | |
private static final AtomicLong total = new AtomicLong(0); | |
private static final ThreadLocal<Long> thinkingTime = | |
new ThreadLocal<Long>() { | |
@Override public Long initialValue() { | |
//return total.getAndIncrement(); | |
return 0L; | |
} | |
@Override public void set(Long ms) { | |
total.set(ms); | |
} | |
@Override public Long get() { | |
return total.get(); | |
} | |
}; | |
public static long get() { | |
return thinkingTime.get(); | |
} | |
public static void set(long ms) { | |
thinkingTime.set(ms); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment