3

I've been building a simple rock, paper, scissors game that's played between two server clients for a college lab. I have a very simple server that starts the game when two clients have signed on. It works like this:

The server creates a game object and waits for player clients to ask for a game.

Once two players request a game the server creates a player 1 object and a player 2 object, passing the game object into their constructors.

The players call methods on the player objects which in turn call methods on game object. The game object has synchronized methods in it.

Each player makes their move, which is stored in the game object, then the game object calculates the winner.

The player objects call the same methods in the game object, this all works fine. But a friend of mine was puzzled by the fact I don't call wait() or notify() in any of my methods. He has already presented his lab, and passed. He asked about wait() and notify() within a synchronized method but he said her response was vague and he still isn't sure, but I should probably put them in just in case. So what's the deal?? Do I need wait() and notify() in a synchronized method?

Also, I read that synchronized doesn't work between Java virtual machines, is this true? If so, how does this affect my game, is synchronized doing anything at all??

Many thanks.

4
  • Take a look here [Java synchronization between different JVMs] [1]: stackoverflow.com/questions/10622724/… Commented Jun 10, 2013 at 20:06
  • you don't need wait()/notifyAll() pair if the only goal is the mutual exclusion, they needed if two or more threads need to co-operate their actions on some data structure, like set of tasks. And none of JVM synchronization primitives works across several JVMs. But, usually, if your code used by several clients over network, you'll get several client-serving threads in your server application, thus, you'd need co-operation between these threads, thus, wait()/notifyAll(), etc. It'd be useful to familiriaze yourself with Oracle threads tutorial (google for it). Commented Jun 10, 2013 at 20:08
  • Thank you for both these comments, they are very helpful. Commented Jun 10, 2013 at 20:30
  • I'm guessing that this is homework, but, in more "real" code, this is a perfect case for a java.util.concurrent.CountDownLatch. Commented Jun 10, 2013 at 21:17

3 Answers 3

2

wait() and notify() are a mechanism for explicit communication between threads within a single JVM. To vastly oversimplify, wait() means something like "It's your turn", and notify() means "OK, I'm done." You never need to add them "just to be safe" -- the idea is absolutely preposterous, in fact.

The synchronized keyword is mainly used to ensure that all threads see the same, valid view of shared data; the problem that it's meant to solve can't come up between separate JVMs, so the fact that it does nothing in that case is fine.

Sign up to request clarification or add additional context in comments.

Comments

0

Without being able to see your code, I can only offer some basic help on Synchronized methods. Synchronization is used to ensure that two threads don't attempt to access or change a resource at the same time, which could then lead to that resource being left in an indeterminate state.

This is an edge case though, so your application might not exhibit any problem when running thousands of times, but that one time that two threads try to both change the same value at once, you'll get an odd error and it won't be easily reproducible.

1 Comment

Thank you for your contribution, this makes sense, the edge case thing.
0

but I should probably put them in just in case. So what's the deal?? Do I need wait() and notify() in a synchronized method?

We can't answer this question without knowing more details about your code. Certainly you should not add them "just in case". If one thread needs to wait for another thread to notify it then yes, you need them. If your algorithm doesn't have the threads signaling each other then you don't need them.

wait() and notify() are typically used when two threads need to communicate. For example, player2 is waiting for player1 to make a move so the player2 thread calls move.wait();. Once player1 has finished his move, the player1 thread calls move.notify(); which causes the player2 thread to continue to run.

There are a number of different ways that your threads can communicate with each other. They can share a BlockingQueue so the player2 thread could call queue.take() which internally handles the locking and signaling for you.

I do wonder how you can write a threaded game program with a shared "game object" without the threads waiting on each other. You say that "Each player makes their move" but this sounds like there needs to be some sort of coordination between the players. But if each player's thread is just waiting for user-input and the user's don't make another move until they see the previous player's move then maybe the wait/notify is being done by the user and not enforced by your program.

Also, I read that synchronized doesn't work between Java virtual machines, is this true? If so, how does this affect my game, is synchronized doing anything at all??

synchronized doesn't work if you are running two separate JVMs -- 2 different Java programs. The synchronized keyword is used to synchronize memory views and to provide mutex locks around critical code when multiple threads are running in the same JVM.

For example, in your game program, if there are two threads working with some sort of shared Game object, they should use the synchronized keyword to ensure that only one thread is making changes to the Game at one time and to make sure that they have the most up-to-date version of the Game state memory.

4 Comments

Ok, thank you for your answer. the method used to set each players move takes the player ID and the move as a parameter, then checks if both players have selected a move, if they have it executes the game, if not it does nothing. When the next player confirms their move it'll do the check again and execute the game.
So it really isn't threaded @mal? Seems like it could be a single thread that is reading the parameters from the user and executing the moves?
hmmm... yeah, it certainly sounds that way doesn't it? But no, the app doesn't play itself, it's two clients connecting to the server over a network. Hang on, now I'm confused. I'll go analyse my code and get back to you. better make sure I'm doing it right!! Thanks for the heads up!
My Player objects implement the runnable interface and a new one is passed to a thread whenever a client logs on to play the game; it's these threads handle the game object with it's synchronized methods.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.