java - Why is my waiting thread not waking up even though it's being notified? -


i have client server tic-tac-toe game attempting run different thread (in different terminals) each player, have built in eclipse.

my goal make each player make move, .notify() other player , .wait() other player make move, , alternate process until game done.

tosync object used synchronization

public static final object tosync = new object() 

and found in player class (which extended both xplayer , oplayer).

the lines seem causing problem commented in xplayer , oplayer:

both xplayer , oplayer have main methods, can run concurrently. x makes first move uses socket communicate move server.
server passes move o, makes own move , passes server. alternates until game done.

making first move x player works fine, once intial move made, o supposed display board , prompt user move. not happen: x makes move, , o supposedly notified, in fact never wakes up. curly brace ending while loop commented in oplayer never reached (which know true debugging i've done far).

class xplayer:

import java.io.*;  public class xplayer  extends player implements runnable {     public static volatile boolean xturn = true;      public xplayer() throws ioexception     {         super();         mark = letter_x;     }      public void run()     {         try         {             system.out.println("okay " + name + ", x-player");              synchronized(tosync)             {                 cell move = makemove();                 out.println(move.tostring());                 board.addmark                     (move.row(),move.col(),move.mark());                 board.display();                  xturn = false;                 tosync.notifyall();    //this line isnt working!!                  system.out.println(waiting);             }             synchronized(tosync)             {                 while (!xturn)                     {tosync.wait();}             }              while (!board.isover())             {                 synchronized(tosync)                 {                     string line;                     {line = in.readline();}                     while (line == null);                         cell opponentmove = cell.split(line);                     board.addmark                         (opponentmove.row(),opponentmove.col(), opponentmove.mark());                      string move = makemove().tostring();                     out.println(move);                     xturn = false;                     tosync.notifyall();                      while (!xturn)                         {tosync.wait();}                 }             }              endgame();              sock.close();             in.close();             stdin.close();             out.close();          } catch (interruptedexception ie)         {             system.out.println("ie in xplayer! " + ie.getmessage());             system.exit(1);          } catch (ioexception ioe)          {             system.out.println("ioe in xplayer! " + ioe.getmessage());             system.exit(1);         }     }     public static void main(string[] args)     {         try         {             xplayer x = new xplayer();             thread t = new thread(x);             t.start();          } catch(ioexception ioe)         {             system.err.println                 ("ioe in xplayer main " + ioe.getmessage());             system.exit(1);         }     } 

class oplayer:

import java.io.*;  public class oplayer  extends player implements runnable {      public oplayer() throws ioexception     {         super();         mark = letter_o;     }      public void run()      {         try         {                    synchronized(tosync)             {                 system.out.println("okay " + name + ", o-player");                  system.out.println(waiting);                 while(!xplayer.xturn)                     {tosync.wait();}    // line isn't waking                  while (!board.isover())                 {                     string line;                      {line = in.readline();}                     while (line == null);                         cell opponentmove = cell.split(line);                     board.addmark                         (opponentmove.row(),opponentmove.col(),opponentmove.mark());                      cell move = makemove();                     out.println(move.tostring());                     board.addmark(move.row(),move.col(),move.mark());                     board.display();                     xplayer.xturn = true;                     tosync.notifyall();                      system.out.println(waiting);                     while (xplayer.xturn)                         {tosync.wait();}                     }             }              endgame();              sock.close();             in.close();             stdin.close();             out.close();          } catch (interruptedexception ie)         {             system.out.println("ie in oplayer " + ie.getmessage());             system.exit(1);          } catch (ioexception ioe)         {             system.err.println("ioe in oplayer " + ioe.getmessage());             system.exit(1);         }     }      public static void main(string[] args)     {         try         {             oplayer o = new oplayer();             thread t = new thread(o);             t.start();          } catch(ioexception ioe)         {             system.err.println("ioe in oplayer main" + ioe.getmessage());             system.exit(1);         }     } } 

as indicated code, tosync.notifyall() call in xplayer not waking oplayer thread, , stuck in deadlock once first move has been made xplayer

i believe 2 classes needed resolve problem in case, here classes player board , tttserver: class player:

import java.net.*; import java.io.*;  public class player implements constants {        protected static final object tosync = new object();      protected socket sock;     protected bufferedreader stdin;     protected bufferedreader in;     protected printwriter out;      protected string name;     protected char mark;     protected board board;      public player() throws ioexception     {         sock = new socket("localhost",1298);         stdin = new bufferedreader(new inputstreamreader(system.in));         in = new bufferedreader(new                  inputstreamreader(sock.getinputstream()));         out = new printwriter(sock.getoutputstream(),true);          system.out.println(welcome);         system.out.println("please enter name:");         name = stdin.readline();         board = new board();     }      public cell makemove() throws ioexception     {         board.display();          int row = -1;         int col = -1;                  {             while (row < 0 || row > 2)             {                    system.out.println                     (name + ", row next move in?");                 row = integer.parseint(stdin.readline());                 if (row < 0 || row > 2)                     {system.out.println("invalid entry! try again...");}             }             while (col < 0 || col > 2)             {                    system.out.println                     (name + ", column next move in?");                 col = integer.parseint(stdin.readline());                 if (col < 0 || col > 2)                     {system.out.println("invalid entry! try again...");}             }              if (board.getmark(row, col) != space_char)                 {system.out.println("that spot taken try again...");}          } while (board.getmark(row,col) != space_char);          return new cell(row,col,mark);     }      public void endgame()     {         if (board.xwins() == 1)     {system.out.println(end + xwin);}         if (board.owins() == 1)     {system.out.println(end + owin);}         else            {system.out.println(end + " tie!!");}     } } 

class tttserver:

import java.net.*; import java.io.*;  public class tttserver implements constants {     public static void main(string[] args)     {         try         {             serversocket ss = new serversocket(1298,2);             system.out.println("the server running...");             socket sock;              board board = new board();              sock = ss.accept();             sock = ss.accept();              bufferedreader in = new bufferedreader(new                      inputstreamreader(sock.getinputstream()));             printwriter out = new printwriter(sock.getoutputstream(),true);                          {                 string movestring;                  {movestring = in.readline();}                 while (movestring == null);                   cell move = cell.split(movestring);                 board.addmark(move.row(), move.col(), move.mark());                  out.println(movestring);              } while(!board.isover());              in.close();             out.close();             ss.close();             sock.close();          } catch(ioexception ioe)         {             system.out.println("ioe in tttserver " + ioe.getmessage());             system.exit(1);         }      } } 

class board:

public class board  implements constants {     /**      * 2d char array stores game board ,       * total number of marks      */     private char theboard[][];     private int markcount;     /**      * default constructor initializes array , fills      * space_chars constants interface      */     public board()      {         markcount = 0;         theboard = new char[3][];         (int = 0; < 3; i++) {             theboard[i] = new char[3];             (int j = 0; j < 3; j++)                 theboard[i][j] = space_char;         }     }     /**      * getter mark @ location specified arguments      *       * @param row      * @param column      *       * @return mark      */     public char getmark(int row, int col)          {return theboard[row][col];}     /**      * getter number of moves have been made far      *       * @return markcount      */     public int getmarkcount()       {return markcount;}     /**      * @return true if game over, otherwise false      */     public boolean isover()     {         if (xwins() == 1 || owins() == 1 || isfull())             {return true;}          return false;     }     /**      * @return true if board has been filled       * x_chars , o_chars constants interface, else false      */     public boolean isfull()          {return markcount == 9;}     /**      * runs checkwinner on letter_x constants interface      *       * @return true if x has won, else false      */     public int xwins()          {return checkwinner(letter_x);}     /**      * runs checkwinner on letter_o constants interface       *       * @return true if o has won, else false      */     public int owins()          {return checkwinner(letter_o);}     /**      * uses formatting helper methods display board       * in console      */     public void display()      {         displaycolumnheaders();         addhyphens();         (int row = 0; row < 3; row++) {             addspaces();             system.out.print("    row " + row + ' ');             (int col = 0; col < 3; col++)                 system.out.print("|  " + getmark(row, col) + "  ");             system.out.println("|");             addspaces();             addhyphens();         }     }     /**      * add mark in last argument location specified       * first 2 arguments      *       * @param row      * @param column      * @param mark      */     public void addmark(int row, int col, char mark)      {         theboard[row][col] = mark;         markcount++;     }     /**      * clears board replacing marks       * space_chars constants interface      */     public void clear()      {         (int = 0; < 3; i++)             (int j = 0; j < 3; j++)                 theboard[i][j] = space_char;         markcount = 0;     }     /**      * checks if player argument mark has won game      *       * @param mark      *       * @return true if game won, else false      */     int checkwinner(char mark) {         int row, col;         int result = 0;          (row = 0; result == 0 && row < 3; row++) {             int row_result = 1;             (col = 0; row_result == 1 && col < 3; col++)                 if (theboard[row][col] != mark)                     row_result = 0;             if (row_result != 0)                 result = 1;         }           (col = 0; result == 0 && col < 3; col++) {             int col_result = 1;             (row = 0; col_result != 0 && row < 3; row++)                 if (theboard[row][col] != mark)                     col_result = 0;             if (col_result != 0)                 result = 1;         }          if (result == 0) {             int diag1result = 1;             (row = 0; diag1result != 0 && row < 3; row++)                 if (theboard[row][row] != mark)                     diag1result = 0;             if (diag1result != 0)                 result = 1;         }         if (result == 0) {             int diag2result = 1;             (row = 0; diag2result != 0 && row < 3; row++)                 if (theboard[row][3 - 1 - row] != mark)                     diag2result = 0;             if (diag2result != 0)                 result = 1;         }         return result;     }      /**      * final 3 helper methods called display       * format board in console      */     void displaycolumnheaders() {         system.out.print("          ");         (int j = 0; j < 3; j++)             system.out.print("|col " + j);         system.out.println();     }      void addhyphens() {         system.out.print("          ");         (int j = 0; j < 3; j++)             system.out.print("+-----");         system.out.println("+");     }      void addspaces() {         system.out.print("          ");         (int j = 0; j < 3; j++)             system.out.print("|     ");         system.out.println("|");     } } 

here's mistake:

both xplayer , oplayer have main methods, can run concurrently.

if you're running 2 main() methods, they're not running "concurrently"; they're entirely separate processes. means no shared threads, variables, objects, notifications etc. if want share state, need start single main() method:

class starterclass {     public static void main(string[] args)     {         // start xplayer thread         try         {             xplayer x = new xplayer();             thread t = new thread(x);             t.start();          } catch(ioexception ioe)         {             system.err.println                 ("ioe in xplayer main " + ioe.getmessage());             system.exit(1);         }          // start oplayer thread         try         {             oplayer o = new oplayer();             thread t = new thread(o);             t.start();          } catch(ioexception ioe)         {             system.err.println("ioe in oplayer main" + ioe.getmessage());             system.exit(1);         }     } } 

if intent have each player run separate client while alternating turns, thread synchronization wrong tool job. you'll need implement custom messaging between server , clients keep them in sync.


Comments

Popular posts from this blog

java - Run spring boot application error: Cannot instantiate interface org.springframework.context.ApplicationListener -

python - pip wont install .WHL files -

Excel VBA "Microsoft Windows Common Controls 6.0 (SP6)" Location Changes -