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 waiting 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

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -