java - Multihreading do I correctly use wait and notify -
i wrote solution of philosophers problem. running , correct output on console println()
after wait()
never printed. please tell me why. pointed out in code.
the solution meant somehting similar http://en.wikipedia.org/wiki/dining_philosophers_problem#resource_hierarchy_solution
public class philosopher extends thread { string name; // boolean je, czeka; int nr; fork left, right; public philosopher(string name, int nr, fork left, fork right) { this.nr = nr; this.name = name; this.left = left; this.right = right; system.out.println("nr " + nr +" "+ left + " " + right); } public void run() { // while(true){ try { fork minf = fork.min(left, right); fork maxf = fork.max(left, right); synchronized (minf) { if (!minf.used) { minf.used = true; system.out.println("p" + nr + " took fork " + minf); } else { minf.wait(); minf.used = true; system.out.println("i waited , took fork " + minf); //why never printeddd??? } synchronized (maxf) { if (!maxf.used) { maxf.used = true; system.out.println("p" + nr + " took fork " + maxf); } else { maxf.wait(); maxf.used = true; system.out.println("i waited , took fork "+ maxf); //why never printeddd?? } system.out.println("i eating right now" + this); eating(); system.out.println("p" + nr + " have eaten giving forks"); minf.used = false; system.out.println("p" + nr + " notify fork" + minf); minf.notify(); maxf.used = false; system.out.println("p" + nr + " notify fork" + maxf); maxf.notify(); } } } catch (exception e) { } // } } public void eating() throws interruptedexception { int time = (int) (math.random() * 2000); (int = 0; < 5; i++) { system.out.println("p" + nr + " " + i); thread.sleep(time / 5); } } public string tostring() { return "philosopher " + nr; } public static void startphilosophers(philosopher[] f) { (int = f.length - 1; >= 0; i--) { f[i].start(); } } public static void main(string[] args) { fork[] t = fork.getarrayofforks(); philosopher[] f = { new philosopher("philosopher 1", 1, t[0], t[4]), new philosopher("philosopher 2", 2, t[1], t[0]), new philosopher("philosopher 3", 3, t[2], t[1]), new philosopher("philosopher 4", 4, t[3], t[2]), new philosopher("philosopher 5", 5, t[4], t[3]), }; startphilosophers(f); } }
public class fork { boolean used; int nr; public fork(boolean used, int nr) { this.used = used; this.nr = nr; } @override public string tostring() { return "f" + nr; } public static fork min(fork l, fork p){ if(l.nr < p.nr) return l; return p; } public static fork max(fork l, fork p){ if(l.nr > p.nr) return l; return p; } public static fork[] getarrayofforks() { fork[] t = new fork[5]; (int = 0; < t.length; i++) { t[i] = new fork(false, (i + 1)); } return t; } }
example output nr 1 f1 f5 nr 2 f2 f1 nr 3 f3 f2 nr 4 f4 f3 nr 5 f5 f4 p5 took fork f4 p5 took fork f5 eating right nowphilosopher 5 p4 took fork f3 p5 0 p2 took fork f1 p2 took fork f2 eating right nowphilosopher 2 p2 0 p5 1 p2 1 p5 2 p2 2 p5 3 p2 3 p5 4 p2 4 p5 have eaten giving forks p5 notify forkf4 p5 notify forkf5 p4 took fork f4 eating right nowphilosopher 4 p4 0 p2 have eaten giving forks p2 notify forkf1 p2 notify forkf2 p3 took fork f2 p1 took fork f1 p1 took fork f5 eating right nowphilosopher 1 p1 0 p1 1 p4 1 p1 2 p4 2 p1 3 p4 3 p1 4 p4 4 p1 have eaten giving forks p1 notify forkf1 p1 notify forkf5 p4 have eaten giving forks p4 notify forkf3 p4 notify forkf4 p3 took fork f3 eating right nowphilosopher 3 p3 0 p3 1 p3 2 p3 3 p3 4 p3 have eaten giving forks p3 notify forkf2 p3 notify forkf3
flup answered question, moving synchronization blocks not sufficient; if yu want use used
flags wait
, notify
, need check condition wait
ing in loop, wait
may return without notify
.
one solution might be:
public class demo { public static class philosopher extends thread { string name; int nr; fork left, right; public philosopher( string name, int nr, fork left, fork right ) { this.nr = nr; this.name = name; this.left = left; this.right = right; system.out.println( "nr " + nr + " " + left + " " + right ); } @override public void run() { // while ( true ) try { fork minf = fork.min( left, right ); fork maxf = fork.max( left, right ); synchronized ( minf ) { if ( ! minf.used ) { minf.used = true; system.out.println( "p" + nr + " took fork " + minf ); } else { while ( minf.used ) // <- need check in loop minf.wait(); minf.used = true; system.out.println( "i waited , took fork " + minf ); // why never printeddd??? } } synchronized ( maxf ) { if ( ! maxf.used ) { maxf.used = true; system.out.println( "p" + nr + " took fork " + maxf ); } else { while ( maxf.used ) // <- need check in loop maxf.wait(); maxf.used = true; system.out.println( "i waited , took fork " + maxf ); // why never printeddd?? } } system.out.println( "i eating right now" + ); eating(); system.out.println( "p" + nr + " have eaten giving forks" ); synchronized ( minf ) { minf.used = false; system.out.println( "p" + nr + " notify fork" + minf ); minf.notify(); } synchronized ( maxf ) { maxf.used = false; system.out.println( "p" + nr + " notify fork" + maxf ); maxf.notify(); } } catch ( exception e ) { // ignore } } public void eating() throws interruptedexception { int time = (int) ( math.random() * 2000 ); ( int = 0; < 5; ++ ) { system.out.println( "p" + nr + " " + ); thread.sleep( time / 5 ); } } public string tostring() { return "philosopher " + nr; } public static void startphilosophers( philosopher[] f ) { ( int = f.length - 1; >= 0; -- ) { f[ ].start(); } } } public static class fork { boolean used; int nr; public fork( boolean used, int nr ) { this.used = used; this.nr = nr; } @override public string tostring() { return "f" + nr; } public static fork min( fork l, fork p ) { if ( l.nr < p.nr ) return l; return p; } public static fork max( fork l, fork p ) { if ( l.nr > p.nr ) return l; return p; } public static fork[] getarrayofforks() { fork[] t = new fork[ 5 ]; ( int = 0; < t.length; ++ ) { t[ ] = new fork( false, ( + 1 ) ); } return t; } } public static void main( string[] args ) { fork[] t = fork.getarrayofforks(); philosopher[] f = { new philosopher( "philosopher 1", 1, t[ 0 ], t[ 4 ] ), new philosopher( "philosopher 2", 2, t[ 1 ], t[ 0 ] ), new philosopher( "philosopher 3", 3, t[ 2 ], t[ 1 ] ), new philosopher( "philosopher 4", 4, t[ 3 ], t[ 2 ] ), new philosopher( "philosopher 5", 5, t[ 4 ], t[ 3 ] ), }; philosopher.startphilosophers( f ); } }
however, sure understand in example, making things overcomplicated. have order on locks, can rid of used
, simplify this:
public class demo2 { public static class philosopher extends thread { string name; int nr; fork left, right; public philosopher( string name, int nr, fork left, fork right ) { this.nr = nr; this.name = name; this.left = left; this.right = right; system.out.println( "nr " + nr + " " + left + " " + right ); } @override public void run() { // while ( true ) try { fork minf = fork.min( left, right ); fork maxf = fork.max( left, right ); synchronized ( minf ) { synchronized ( maxf ) { system.out.println( "i eating right now" + ); eating(); system.out.println( "p" + nr + " have eaten giving forks" ); } } } catch ( exception e ) { // ignore } } public void eating() throws interruptedexception { int time = (int) ( math.random() * 2000 ); ( int = 0; < 5; ++ ) { system.out.println( "p" + nr + " " + ); thread.sleep( time / 5 ); } } public string tostring() { return "philosopher " + nr; } public static void startphilosophers( philosopher[] f ) { ( int = f.length - 1; >= 0; -- ) { f[ ].start(); } } } public static class fork { int nr; public fork( int nr ) { this.nr = nr; } @override public string tostring() { return "f" + nr; } public static fork min( fork l, fork p ) { if ( l.nr < p.nr ) return l; return p; } public static fork max( fork l, fork p ) { if ( l.nr > p.nr ) return l; return p; } public static fork[] getarrayofforks() { fork[] t = new fork[ 5 ]; ( int = 0; < t.length; ++ ) { t[ ] = new fork( + 1 ); } return t; } } public static void main( string[] args ) { fork[] t = fork.getarrayofforks(); philosopher[] f = { new philosopher( "philosopher 1", 1, t[ 0 ], t[ 4 ] ), new philosopher( "philosopher 2", 2, t[ 1 ], t[ 0 ] ), new philosopher( "philosopher 3", 3, t[ 2 ], t[ 1 ] ), new philosopher( "philosopher 4", 4, t[ 3 ], t[ 2 ] ), new philosopher( "philosopher 5", 5, t[ 4 ], t[ 3 ] ), }; philosopher.startphilosophers( f ); } }
Comments
Post a Comment