• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

synchronization.. and threads !!!

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a TicTacToe game which is played betwee 2 players and a server manages the rule base..
I dont understand a part of the code. I am providing a link to the code as well, but for simplicity i shall write the code for the Server and the Client here itself.. it will make my message too long, sorry for that. here goes the code.the Server Program first and then the Client Program... and then my query...
****************************************************************
//TicTacToeServer.java This class maintains a game of Tic-Tac-Toe for two
// client applets.
import java.awt.*; import java.awt.event.*; import java.net.*;
import java.io.*; import javax.swing.*;
public class TicTacToeServer extends JFrame {
private byte board[];
private boolean xMove;
private JTextArea output;
private Player players[];
private ServerSocket server;
private int currentPlayer;
public TicTacToeServer() {
super( "Tic-Tac-Toe Server" );
board = new byte[ 9 ];
xMove = true;
players = new Player[ 2 ];
currentPlayer = 0;
// set up ServerSocket
try { server = new ServerSocket( 5000, 2 ); }
catch( IOException e ) {
e.printStackTrace(); System.exit( 1 ); }
output = new JTextArea();
getContentPane().add( output, BorderLayout.CENTER );
output.setText( "Server awaiting connections\n" );
setSize( 300, 300 );show();
}
// wait for two connections so game can be played
public void execute() {
for ( int i = 0; i < players.length; i++ ) {
try {players[ i ] = new Player( server.accept(), this, i );
players[ i ].start(); }
catch( IOException e ) {
e.printStackTrace(); System.exit( 1 ); }
}
// Player X is suspended until Player O connects. Resume player X now.
synchronized(players[0]) {
players[0].threadSuspended = false; players[0].notify(); }
}
public void display( String s )
{output.append( s + "\n" ); }
// Determine if a move is valid. This method is synchronized because only
// one move can be made at a time.
public synchronized boolean validMove( int loc, int player ) {
boolean moveDone = false;
while ( player != currentPlayer ) {
try { wait(); }
catch( InterruptedException e ) { e.printStackTrace(); }
}
if ( !isOccupied( loc ) ) {
board[ loc ] =
(byte) ( currentPlayer == 0 ? 'X' : 'O' );
currentPlayer = ( currentPlayer + 1 ) % 2;
players[ currentPlayer ].otherPlayerMoved( loc );
notify(); // tell waiting player to continue
return true;
}
else return false;
}
public boolean isOccupied( int loc )
{
if ( board[ loc ] == 'X' | | board [ loc ] == 'O' ) return true;
else return false;
}
public boolean gameOver()
{ // Place code here to test for a winner of the game
return false; }
public static void main( String args[] )
{ TicTacToeServer game = new TicTacToeServer();
game.addWindowListener( new WindowAdapter() {
public void windowClosing( WindowEvent e )
{ System.exit( 0 ); }
} );
game.execute();
}
}
// Player class to manage each Player as a thread
class Player extends Thread {
private Socket connection;
private DataInputStream input;
private DataOutputStream output;
private TicTacToeServer control;
private int number;
private char mark;
protected boolean threadSuspended = true;
public Player( Socket s, TicTacToeServer t, int num )
{ mark = ( num == 0 ? 'X' : 'O' );
connection = s;
try { input = new DataInputStream(connection.getInputStream() );
output = new DataOutputStream(connection.getOutputStream() );}
catch( IOException e ) { e.printStackTrace(); System.exit( 1 ); }
control = t; number = num;
}
public void otherPlayerMoved( int loc )
{
try {
output.writeUTF( "Opponent moved" );
output.writeInt( loc );
}
catch ( IOException e ) { e.printStackTrace(); }
}
public void run()
{
boolean done = false;
try {
control.display( "Player " +
( number == 0 ? 'X' : 'O' ) + " connected" );
output.writeChar( mark );
output.writeUTF( "Player " +
( number == 0 ? "X connected\n" :
"O connected, please wait\n" ) );
// wait for another player to arrive
if ( mark == 'X' ) {
output.writeUTF( "Waiting for another player" );
try {
synchronized( this ) {
while ( threadSuspended )
wait();
}
}
catch ( InterruptedException e ) {
e.printStackTrace();
}
output.writeUTF(
"Other player connected. Your move." );
}
// Play game
while ( !done ) {
int location = input.readInt();
if ( control.validMove( location, number ) ) {
control.display( "loc: " + location );
output.writeUTF( "Valid move." );
}
else
output.writeUTF( "Invalid move, try again" );
if ( control.gameOver() )
done = true;
}
connection.close();
}
catch( IOException e ) {
e.printStackTrace();
System.exit( 1 );
}
}
}
*****************************************************************
// Fig. 21.8: TicTacToeClient.java
// Client for the TicTacToe program
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import javax.swing.*;
// Client class to let a user play Tic-Tac-Toe with
// another user across a network.
/*<applet code="TicTacToeClient.class" width=500 height=500></applet>*/
public class TicTacToeClient extends JApplet
implements Runnable {
private JTextField id;
private JTextArea display;
private JPanel boardPanel, panel2;
private Square board[][], currentSquare;
private Socket connection;
private DataInputStream input;
private DataOutputStream output;
private Thread outputThread;
private char myMark;
private boolean myTurn;
// Set up user-interface and board
public void init()
{
display = new JTextArea( 4, 30 );
display.setEditable( false );
getContentPane().add( new JScrollPane( display ),
BorderLayout.SOUTH );
boardPanel = new JPanel();
GridLayout layout = new GridLayout( 3, 3, 0, 0 );
boardPanel.setLayout( layout );
board = new Square[ 3 ][ 3 ];
// When creating a Square, the location argument to the
// constructor is a value from 0 to 8 indicating the
// position of the Square on the board. Values 0, 1,
// and 2 are the first row, values 3, 4, and 5 are the
// second row. Values 6, 7, and 8 are the third row.
for ( int row = 0; row < board.length; row++ )
{
for ( int col = 0;
col < board[ row ].length; col++ ) {
board[ row ][ col ] =
new Square( ' ', row * 3 + col );
board[ row ][ col ].addMouseListener(
new SquareListener(
this, board[ row ][ col ] ) );
boardPanel.add( board[ row ][ col ] );
}
}
id = new JTextField();
id.setEditable( false );
getContentPane().add( id, BorderLayout.NORTH );
panel2 = new JPanel();
panel2.add( boardPanel, BorderLayout.CENTER );
getContentPane().add( panel2, BorderLayout.CENTER );
}
// Make connection to server and get associated streams.
// Start separate thread to allow this applet to
// continually update its output in text area display.
public void start()
{
try {
//connection = new Socket(InetAddress.getByName( "127.0.0.1" ), 5000 );
connection = new Socket(InetAddress.getByName( "131.183.22.11" ), 5000 );
input = new DataInputStream(
connection.getInputStream() );
output = new DataOutputStream(
connection.getOutputStream() );
}
catch ( IOException e ) {
e.printStackTrace();
}
outputThread = new Thread( this );
outputThread.start();
}
// Control thread that allows continuous update of the
// text area display.
public void run()
{
// First get player's mark (X or O)
try {
myMark = input.readChar();
id.setText( "You are player \"" + myMark + "\"" );
myTurn = ( myMark == 'X' ? true : false );
}
catch ( IOException e ) {
e.printStackTrace();
}
// Receive messages sent to client
while ( true ) {
try {
String s = input.readUTF();
processMessage( s );
}
catch ( IOException e ) {
e.printStackTrace();
}
}
}
// Process messages sent to client
public void processMessage( String s )
{
if ( s.equals( "Valid move." ) ) {
display.append( "Valid move, please wait.\n" );
currentSquare.setMark( myMark );
currentSquare.repaint();
}
else if ( s.equals( "Invalid move, try again" ) ) {
display.append( s + "\n" );
myTurn = true;
}
else if ( s.equals( "Opponent moved" ) ) {
try {
int loc = input.readInt();
board[ loc / 3 ][ loc % 3 ].setMark(
( myMark == 'X' ? 'O' : 'X' ) );
board[ loc / 3 ][ loc % 3 ].repaint();
display.append(
"Opponent moved. Your turn.\n" );
myTurn = true;
}
catch ( IOException e ) {
e.printStackTrace();
}
}
else
display.append( s + "\n" );
display.setCaretPosition(
display.getText().length() );
}
public void sendClickedSquare( int loc )
{
if ( myTurn )
try {
output.writeInt( loc );
myTurn = false;
}
catch ( IOException ie ) {
ie.printStackTrace();
}
}
public void setCurrentSquare( Square s )
{
currentSquare = s;
}
}
// Maintains one square on the board
class Square extends JPanel {
private char mark;
private int location;
public Square( char m, int loc)
{
mark = m;
location = loc;
setSize ( 30, 30 );
setVisible(true);
}
public Dimension getPreferredSize() {
return ( new Dimension( 30, 30 ) );
}
public Dimension getMinimumSize() {
return ( getPreferredSize() );
}
public void setMark( char c ) { mark = c; }
public int getSquareLocation() { return location; }
public void paintComponent( Graphics g )
{
super.paintComponent( g );
g.drawRect( 0, 0, 29, 29 );
g.drawString( String.valueOf( mark ), 11, 20 );
}
}
class SquareListener extends MouseAdapter {
private TicTacToeClient applet;
private Square square;
public SquareListener( TicTacToeClient t, Square s )
{
applet = t;
square = s;
}
public void mouseReleased( MouseEvent e )
{
applet.setCurrentSquare( square );
applet.sendClickedSquare( square.getSquareLocation() );
}
}
*****************************************************************
Now my Query... refer to the execute() method of the server class
public void execute() {
for ( int i = 0; i < players.length; i++ ) {
try {
players[i]=new Player(server.accept(),this,i);
players[ i ].start();
}
catch( IOException e ) {
e.printStackTrace();
System.exit( 1 );
}
}
// Player X is suspended until Player O connects.
// Resume player X now.
synchronized(players[0]) {
players[0].threadSuspended = false;
players[0].notify();
}
}
i didnt quite understand what the synchronized(players[0]) means
and under what condition will the block get executed, and which thread will be able to execute it.
this was quite a mouthful of a message. thanks in advance for a patient reading. any response will be highly appreciated. im trying to write a server that plays the card game FLASH between 2 to 4 players.
amitapt@hotmail.com
 
Ranch Hand
Posts: 232
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Amit,
You must post code between the [ C O D E ] and [ / C O D E ] tags (but without the spaces) if you wish it to come out formatted correctly.
This is also likely too much code to post at one time. No one is likely to have the time to read through and study it for you. If you try and narrow down your question to something shorter and more specific, you may have better luck.
 
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
amit, here is how I'm interpreting the code. based on your question I have only read the relevant code. you have altogether 3 threads, the main server thread, and 2 player threads player[0] and player[1]. server thread starts the player[0] thread or 'X' thread and goes into wait(). the server thread then starts the player[1] thread. the synchronized(player[0]) indicates that the server thread has to acquire the monitor for player[0] before it can enter this block. since player[0] itself is in wait state it has relinquished it's own monitor. since no other thread has acquired the monitor of player[0] it is up for grabs. the server thread acquires it and sets the threadRunning flag to false and invokes notify which in turns wakes up the player[0] thread. as soon as the server thread comes out of the synchronized block it relinquishes the monitor. player[0] thread acquires the monitor and resumes the execution.
player[1] never enters the synchronized block.
thanks,
GP
 
Amit Tamhankar
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks GP.. theres a hell lot to study in threads i presume.. is Java much more vast than VC, which is a system programming medium. where did u get to set the ThreadRunnign flag etc.. does it exist for all classes extending Thread/impplementing Runnable ?
thanks again.. seems like i have to read about monitors..
what are good reference links to understand them with Javas Perspective.
Thanks again.
Amit
 
Girish Pednekar
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
amit, I misstated the variable name as threadRunning. it's actually threadSuspended and it's in your code. I hope I didn't lead you to believe that each thread has a built-in variable threadRunning.
thanks,
GP
 
My cellmate was this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic