concurrency - Dining philosophers in java -
today, decide try solve dining philosophers problem. write code below. think not correct, pleased if tells me wrong it. use forks locks ( read them, because of don't put access them in synchronized blocks), have class extends thread , keeps 2 locks.
import java.util.random; public class eatingphilosophersproblem { private final static random random = new random(); /** * * @author damyan class represents eating of every philosopher. * represents infinity cycle of eating. */ private static class philosophereating extends thread { int forkone; int forktwo; public philosophereating(string name, int forkone, int forktwo) { super(name); this.forkone = forkone; this.forktwo = forktwo; } @override public void run() { super.run(); while (true) { requirelock(this, forkone, forktwo); } } } private static boolean[] forks = new boolean[] { new boolean(true), new boolean(true), new boolean(true), new boolean(true), new boolean(true) }; // locks should created new, otherwise 100% sure // point same object (because of java pools) // pools used java immutable objects private static void requirelock(philosophereating philosophereating, int firstindex, int secondindex) { // lock the lower index higher, otherwise // every philosopher can take left fork , deadlock apear if (firstindex > secondindex) { int temp = firstindex; firstindex = secondindex; secondindex = temp; } if (firstindex == 4 || secondindex == 4) { system.err.println(firstindex + " , " + secondindex); } synchronized (forks[firstindex]) { synchronized (forks[secondindex]) { printphilosopherhaction(philosophereating, "start eating"); try { thread.sleep(random.nextint(100)); } catch (interruptedexception e) { e.printstacktrace(); } printphilosopherhaction(philosophereating, "stop eating"); } } }; private static void printphilosopherhaction(philosophereating philosophereating, string action) { system.out.println("philosopher " + philosophereating.getname() + " " + action); } public static void main(string[] args) { philosophereating first = new philosophereating("1 - first", 0, 1); philosophereating second = new philosophereating("2 - second", 1, 2); philosophereating third = new philosophereating("3 - third", 2, 3); philosophereating fourth = new philosophereating("4 - fourth", 3, 4); philosophereating fifth = new philosophereating("5 - fifth", 4, 0); first.start(); second.start(); third.start(); fourth.start(); fifth.start(); }
i think wrong, because fifth philosopher never eating, fourth , third philosophers eat. in advance.
there name problem: called thread "starvation". it's happens when several threads competing same resource, , 1 (or more) of them continually denied access.
figuring out how avoid deadlocks 1 aspect of dining philosophers puzzle, figuring out how let each philosopher fair amount of eating time can aspect.
jp moresmau's answer suggested force each philosopher take break (often called "thinking" in classic puzzle) other philosophers turn eat. works, if think of philosophers worker threads in application, "eating" corresponds worker thread doing useful work, , "resting" or "thinking" corresponds thread sitting idle, might you'd wish avoid.
it takes more locks make sure of philosophers fair share of eating time if of them hungry.
here's hint: higher-level synchronization objects make kind of "fairness" guarantee use queues in implementation.
Comments
Post a Comment