I am wondering how exactly "synchronized" works in java.
Let's say I model a board-game that consists of a number of fields. I implement the fields as a class (Field) and the board as a class (Board) that contains a number of fields. Let's further say I modelled a method moveTo(Player pl) in Field, for a player to move to that field. Each player is represented by a thread.
Although all the threads should do some actions simultaneously (for example rolling their dices), there should only be one player that moves at a time.
How would I ensure that? Is it enough to make the method moveTo(Player pl) synchronized? Or would I need a cascading method in Board to make sure that only one player moves at a time? (Or is there a better solution)?
To bring it to the bottom line:
Would "synchronized" lock a method in EVERY object that has this method or would synchronized lock a method only in the object that is currently in use?
And if the second is the case: is there an easy way to lock a method for every object that has this method implemented?
Thank you!!!
When we use a synchronized block, Java internally uses a monitor, also known as monitor lock or intrinsic lock, to provide synchronization. These monitors are bound to an object; therefore, all synchronized blocks of the same object can have only one thread executing them at the same time.
The synchronized keyword prevents concurrent access to a block of code or object by multiple threads. All the methods of Hashtable are synchronized , so only one thread can execute any of them at a time.
Whenever we are using a synchronized keyword, then only the lock concept will come into the picture. If a thread wants to execute then synchronized method on the given object. First, it has to get a lock-in that object. Once the thread got the lock then it is allowed to execute any synchronized method on that object.
with locks, you can release and acquire the locks in any order. with synchronized, you can release the locks only in the order it was acquired.
What I think you would want is the following:
class Field {
// instance of the board
private Board board;
public void moveTo(Player p){
synchronized (board) {
// move code goes here
}
}
}
This will make it so that per board, only one player is moving at a time. If you get the synchronization lock on the board, only one Field may enter the synchronized lock at a time. (Assuming one board)
If you simply wrote:
public synchronized void moveTo(Player p){
you would only be assuring that players couldn't move to the same Field at a time. This is because when a method is written with synchronized in the definition, it will lock at the object level. So, each instance of Field will be it's own lock object, and thus, players could still move at the same time as long as they weren't moving to the same Field.
synchronized locks an object, not a method. Java doesn't have functions.
If you want a method to be called only once across all object you can lock on a shared object, such as the class.
I would suggest you only need one thread to perform all the moves/operations and this would simplify the code significantly. Why does it have to be multi-threaded?
Synchronisation locks access to a resource. That resource can either be a function or an object (Including the this
object).
We can't give you specific advice without a specific example.
In your example, if the players can only take 1 turn at a time, why do they need to be in their own threads? Why do they need to roll their dice at the same time?
synchronising a function locks calls to that instance's version of that method (unless it's a static method).
And if the second is the case: is there an easy way to lock a function for every object that has this function implemented?
This seems to suggest that your design could be re-evaluated. Do your object's instance methods really share state such that they need their methods synchronised with each other? Why?
It depends on where it is used.
If used in a typical method, it exclusively grabs the "lock" object of the Object in question. No other Thread can process methods in that object if they need exclusive access to the same Object's "lock" object (non-synchronized methods don't require exclusive access to the lock).
If used in a static method, it exclusively grabs the lock object of the Object representing the Class. No other Thread can process methods in that Class object if they need exclusive access to the same Class Object's "lock" object (non-synchronized methods don't require exclusive access to the lock).
If used with an explicitly stated object, it exclusively grabs the lock object of the explicitly stated object. Again, no other Thread can exclusively grab the lock of that object during that time.
Once you leave the scope of a synchronized block, you relinquish your exclusive hold on the lock.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With