How Does Synchronized Work in Java

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:

  1. The first Thread started calls alphonse.bow(gaston), which is synchronized on the alphonse Friend object. This means the Thread must acquire the lock from this object.
  2. The second Thread started calls gaston.bow(alphonse), which is synchronized on the gaston Friend object. This means the Thread must acquire the lock from this object.
  3. The first thread started now calls bowback and waits for the lock on gaston to be released.
  4. The second thread started now calls bowback and waits for the lock on alphonse to be released.

To show the sequence of events in much more detail:

  1. main() begins to execute in the main Therad (call it Thread #1), creating two Friend instances. So far, so good.
  2. The main Thread starts its first new Thread (call it Thread #2) with the code new Thread(new Runnable() { .... Thread #2 calls alphonse.bow(gaston), which is synchronized on the alphonse Friend object. Thread #2 thus acquires the "lock" for the alphonse object and enters the bow method.
  3. A time slice occurs here and the original Thread gets a chance to do more processing.
  4. 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 the gaston Friend object. Since no-one has yet acquired the "lock" for the gaston object instance, Thread #3 successfully acquires this lock and enters the bow method.
  5. A time slice occurs here and Thread #2 gets a chance to do more processing.
  6. Thread #2 now calls bower.bowBack(this); with bower being a reference to the instance for gaston. This is the logical equivalent of a call of gaston.bowBack(alphonse). Thus, this method is synchronized on the gaston 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 on gaston to be released. The Thread is put into a waiting state, allowing Thread #3 to execute further.
  7. Thread #3 now calls bowback, which in this instance is logically the same as the call alphonse.bowBack(gaston). To do this, it needs to acquire the lock for the alphonse 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 other static 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.

Java monitor entry set 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 in Entry 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



Leave a reply



Submit