How does synchronized work in Java
In Java, each Object
provides the ability for a Thread to synchronize
, or lock, on it. When a method is synchronized, the method uses its object instance as the lock. In your example, the methods bow
and bowBack
are both synchronized
, and both are in the same class Friend
. This means that any Thread executing these methods will synchronize on a Friend
instance as its lock.
A sequence of events which will cause a deadlock is:
- The first Thread started calls
alphonse.bow(gaston)
, which issynchronized
on thealphonse
Friend
object. This means the Thread must acquire the lock from this object. - The second Thread started calls
gaston.bow(alphonse)
, which issynchronized
on thegaston
Friend
object. This means the Thread must acquire the lock from this object. - The first thread started now calls
bowback
and waits for the lock ongaston
to be released. - The second thread started now calls
bowback
and waits for the lock onalphonse
to be released.
To show the sequence of events in much more detail:
main()
begins to execute in the main Therad (call it Thread #1), creating twoFriend
instances. So far, so good.- The main Thread starts its first new Thread (call it Thread #2) with the code
new Thread(new Runnable() { ...
. Thread #2 callsalphonse.bow(gaston)
, which issynchronized
on thealphonse
Friend
object. Thread #2 thus acquires the "lock" for thealphonse
object and enters thebow
method. - A time slice occurs here and the original Thread gets a chance to do more processing.
- The main Thread starts a second new Thread (call it Thread #3), just like the first one. Thread #3 calls
gaston.bow(alphonse)
, which is synchronized on thegaston
Friend
object. Since no-one has yet acquired the "lock" for thegaston
object instance, Thread #3 successfully acquires this lock and enters thebow
method. - A time slice occurs here and Thread #2 gets a chance to do more processing.
- Thread #2 now calls
bower.bowBack(this);
withbower
being a reference to the instance forgaston
. This is the logical equivalent of a call ofgaston.bowBack(alphonse)
. Thus, this method issynchronized
on thegaston
instance. The lock for this object has already been acquired and is held by another Thread (Thread #3). Thus, Thread #2 has to wait for the lock ongaston
to be released. The Thread is put into a waiting state, allowing Thread #3 to execute further. - Thread #3 now calls
bowback
, which in this instance is logically the same as the callalphonse.bowBack(gaston)
. To do this, it needs to acquire the lock for thealphonse
instance, but this lock is held by Thread #2. This Thread is now put into a waiting state.
And you are now in a position where neither Thread can execute. Both Thread #2 and Thread #3 are waiting for a lock to be released. But neither lock can be released without a Thread making progress. But neither thread can make progress without a lock being released.
Thus: Deadlock!
Deadlocks very often depend on a specific sequence of events occurring, which can make then difficult to debug since they can be difficult to reproduce.
How Synchronization works in Java?
Synchronization in java is done through aquiering the monitor on some specific Object. Therefore, if you do this:
class TestClass {
SomeClass someVariable;
public void myMethod () {
synchronized (someVariable) {
...
}
}
public void myOtherMethod() {
synchronized (someVariable) {
...
}
}
}
Then those two blocks will be protected by execution of 2 different threads at any time while someVariable
is not modified. Basically, it's said that those two blocks are synchronized against the variable someVariable
.
When you put synchronized
on the method, it basically means the same as synchronized (this)
, that is, a synchronization on the object this method is executed on.
That is:
public synchronized void myMethod() {
...
}
Means the same as:
public void myMethod() {
synchronized (this) {
...
}
}
Therefore, to answer your question - yes, threads won't be able to simultaneously call those methods in different threads, as they are both holding a reference to the same monitor, the monitor of this
object.
What does 'synchronized' mean?
The synchronized
keyword is all about different threads reading and writing to the same variables, objects and resources. This is not a trivial topic in Java, but here is a quote from Sun:
synchronized
methods enable a simple
strategy for preventing thread
interference and memory consistency
errors: if an object is visible to
more than one thread, all reads or
writes to that object's variables are
done through synchronized methods.
In a very, very small nutshell: When you have two threads that are reading and writing to the same 'resource', say a variable named foo
, you need to ensure that these threads access the variable in an atomic way. Without the synchronized
keyword, your thread 1 may not see the change thread 2 made to foo
, or worse, it may only be half changed. This would not be what you logically expect.
Again, this is a non-trivial topic in Java. To learn more, explore topics here on SO and the Interwebs about:
- Concurrency
- Java Memory Model
Keep exploring these topics until the name "Brian Goetz" becomes permanently associated with the term "concurrency" in your brain.
How does the synchronize functionality work in java?
Under the hood it is using two opcodes monitorenter
and monitorexit
at the byte code level which acquire/release locks on an object reference at a JVM global level. I highly recommend you read How the Java virtual machine performs thread synchronization.
Does synchronized work for all methods in a class or only 1?
The JLS, § 17.1 is quite verbose about this:
A synchronized method (§8.4.3.6) automatically performs a lock action when it is invoked; its body is not executed until the lock action has successfully completed. If the method is an instance method, it locks the monitor associated with the instance for which it was invoked (that is, the object that will be known as
this
during execution of the body of the method). If the method is static, it locks the monitor associated with the Class object that represents the class in which the method is defined. If execution of the method's body is ever completed, either normally or abruptly, an unlock action is automatically performed on that same monitor.
Oracle's official tutorial on synchronized Methods phrases it a little bit more understandable:
...
- First, it is not possible for two invocations of synchronized methods on the same object to interleave. ...
...
What does A synchronized block in Java is synchronized on some object mean..?
The effect of synchronized
is that only one thread at a time can execute the synchronized code. But if we look at the details, that's not the whole truth.
Suppose we have two Vectors A
and B
and want to call various methods from different threads. The Vector
class is thread-safe by synchronizing all important methods. When thread T1 executes A.add(5,"abc")
, why should that block a different thread from executing B.get(5)
? They have no data elements in common, so executing both calls in parallel won't hurt.
And here comes the notion of "synchronized on A": The Vector
methods synchronize on the Vector
instance, so at most one thread can execute synchronized code for any given Vector.
So Vector A synchronizes on A, and Vector B on B. So, no two threads can manipulate the Vector A in parallel, but one thread can work on A, and another one independently on B.
- With the
synchronized(object) { ... }
construct, you decide on the object you want to synchronize on. - Using the
synchronized
keyword on an instance method, you get synchronization on the current (this
) object, so every instance gets its own synchronization. - Using the
synchronized
keyword on a static method, you get synchronization on the class, so you get protection against all otherstatic synchronized
methods of this class, independent of any instance.
What is happening behind Synchronized?
The doubt is how the below code snippet will make the program
thread-safe?
The key thing here is that each java object has an implicit monitor associated with it and only one thread can enter the object monitor at any point of time and other threads that are trying to enter this monitor will be in queued either entry set or wait set.
And when a thread tries to executes a method that is marked as synchronized
it is should get the ownership of the implicit monitor
before executing the code in that method.
In your case you have two methods and both marked as synchronized
. Since with the synchronized
keyword only one thread will be able get hold of the object monitor that is needed to execute either of these methods, at any point only one thread can execute these synchronized
method and thus they are thread-safe.
What is happening behind the scenes?
To understand how the object monitor, ownership, wait set and entry set work together, let us take the below picture that represents an implicit monitor
that is unique for each java object. As we see, there are has two entry points to acquire the monitor i.e., from Entry Set
or from Wait Set
. For our discussion we will the flow only from Entry Set
perspective and assume an empty Wait Set
.
As the thread calls the synchronized
method it is placed in the Entry Set
.
- If no thread currently owns the monitor and no other threads are waiting in the entry set, the thread becomes the owner of the monitor and starts executing the code. This is called the active thread.
- Else, if there is another thread that is owning the monitor, the current thread is placed in the
Entry set
and will have to wait for its turn along with other already existing threads inEntry Set
, if any.
While the current thread is waiting in the Entry Set
,
- The active thread will release the monitor when it is done with executing the code in the synchronized block. (other way of releasing is through
wait()
method that we will ignore for our discussion) - Subsequently, as the monitor is free now, the threads in the entry set will compete to acquire the monitor and one of them will get a chance.
NOTE : As indicated above, for the above discussion, we have assumed that there are no threads in the Wait Set
for simplicity to keep discussion to the point. Wait Set
comes into the picture with wait()
and notify()
calls.
I suggest and it is worth having a look at https://www.artima.com/insidejvm/ed2/threadsynchP.html for more detailed explanation on the monitors, entry set & wait set.
What is the use of static synchronized method in java?
In general, synchronized
methods are used to protect access to resources that are accessed concurrently. When a resource that is being accessed concurrently belongs to each instance of your class, you use a synchronized
instance method; when the resource belongs to all instances (i.e. when it is in a static
variable) then you use a synchronized static
method to access it.
For example, you could make a static
factory method that keeps a "registry" of all objects that it has produced. A natural place for such registry would be a static
collection. If your factory is used from multiple threads, you need to make the factory method synchronized
(or have a synchronized
block inside the method) to protect access to the shared static
collection.
Note that using synchronized
without a specific lock object is generally not the safest choice when you are building a library to be used in code written by others. This is because malicious code could synchronize on your object or a class to block your own methods from executing. To protect your code against this, create a private "lock" object, instance or static, and synchronize on that object instead.
In this synchronization is not working. Why? I have synchronized all methods. Can anyone please tell and provide solution for the same?
A synchronized method will prevent other threads to enter into a synchronized block on the same object the method is synchronized on. Each thread has two methods in your example, so for instance while first
is running, second
cannot run, but there is nothing to prevent third
from running.
You need to synchronize all methods on the same object:
Object s=new Object();
A a1=new A(s);
B b1=new B(s);
C c1=new C(s);
class A implements Runnable{
Object s;
public A(s Object) {
this.s=s;
}
public void first(){
synchronized(s) {
for(int i=0;i<=10;i++){
System.out.println("Table of 13 is "+13*i);
}
}
}
Related Topics
How to Properly Match Varargs in Mockito
Format Double Value in Scientific Notation
Is There a Good Natural Language Processing Library
Read Properties File Outside Jar File
How to Get Out of While Loop in Java with Scanner Method "Hasnext" as Condition
How to Set the System Time in Java
Is an Array a Primitive Type or an Object (Or Something Else Entirely)
Collection to Stream to a New Collection
Multi-Project Test Dependencies with Gradle
How to Force Selenium Webdriver to Click on Element Which Is Not Currently Visible
Sorting Arraylist in Alphabetical Order (Case Insensitive)
How to Catch Out of Memory Exception in Java
How to Inject Authenticationmanager Using Java Configuration in a Custom Filter
Does Setting Java Objects to Null Do Anything Anymore
How to Write a Java Application That Can Update Itself at Runtime