Synchronization in Java | Inter Thread Communication – Part 2

This leaflet is an immediate successor of multithreading and will try to answer – What is synchronization in Java and take a look at some examples to drive that nail further in. You will also learn about thread messaging and communication hereby which will help you to understand things better.

Without further ado, let’s get to understanding everything about synchronization in Java and how does it fit in with multithreading.

What is synchronization in Java?

When there are many threads trying to access one shared resource, and are trying to fight over priorities, it isn’t good for your program. You might face inconsistency issues or unexpected thread interference.

To make sure a resource is being used by just one thread at a time, we make use of synchronization.

Look at it as a snack someone offers to you and your family when you visit their house. Each person in the room is a thread, and that delicious snack in the middle is a shared resource. Now wearing a mask of a good lad you are supposed to allow everyone to get a piece of it. That’s you and your siblings behaving in a synchronized way. That’s what synchronization in Java is about too.

joey doesn't share food meme
It is a different story altogether if the same snack is offered to you in your own house. Hell would unleash. You hog on it showing your true colors.

There are two types of synchronization in Java namely:

  1. Mutually Exclusive (mutex)
  2. Cooperation (Inter-thread communication)

Mutually Exclusive or Mutex

We have a monitor (also called semaphore) used as a mutually exclusive lock or mutex. So, when a thread is said to have acquired a lock, it has basically entered a monitor. Only one thread can hold a lock on a monitor at one time.

There are three ways to achieve mutex. They are:

  • using synchronized method
  • using synchronized block
  • using static synchronization

You need to remember that every object in Java has its own implicit monitor which a thread can lock or unlock. If you want to enter an object’s monitor you just have to call a method modified with synchronized keyword.

Example without Synchronization

Before we begin to learn about synchronization in java using synchronized keywords, it is important to see what could go wrong without using it. We saw a lot of examples in the previous chapter of multithreading but it wouldn’t hurt to see one more.

Here’s a quick example for the same.

Water is one class that is trying to display a message we pass in square brackets.

water class in java
Another one of our class where Runnable is implemented is Fire:

Second class that implements Runnable called Fire

This class has the inevitable run() method that has to be started using start(). I have put that call in its constructor. Notice we have parameterized the constructor to hold object of Water and a String. Thread instance has been declared as well, so as to kick start run.

That leaves us with the main method where we will make necessary calling arrangements:

main method in java

If you run the above program you will get the following unsynchronized result:

[First call]
[Hey[What up?]
]

The result might differ based on your CPU processing.

Using Synchronized Method

We wanted a proper syncing, didn’t we? So that blocks were closed when they should have been. That’s where synchronization in Java comes into the picture.

The above example can be taken care of by one minor adjustment. Make the display method synchronized by adding the synchronized keyword like this:

method with synchronized keyword
The moment you do JVM understands that you want to lock this method until everything is run before moving on to the next thread.

If you try to run the above program now, you will get a much better result:

[First call] 
[Hey] 
[What up?]

Using Synchronized Block

An alternative to the above is by simply using the synchronized block. Synchronized blocks come in handy when you have a whole lot of code in your method and you just want to use it for few lines. You can simply choose to synchronize a block rather than the whole method.

It is obvious that the scope of synchronized block will be lesser than that of the synchronized method.

Here’s the syntax you need to remember:

synchronized (object) {
-----stuff that needs to be synchronized------
}

In our example above, simply go to the run() method and put calling display around a synchronized block and pass the object as an argument.

Include synchronized keyword by creating a synchronized block like this:

synchronized method example in java

Now if you will run the program again, you will get the following output:

[First call]
[Hey]
[What up?]

Neat, huh?

Using Static Synchronization

As implied by the definition of static, when you want the lock on the “class” and not on the object you make use of static synchronization in Java.

So by definition it means – only one thread can access the class at one time.

Taking the above example and turning the method into a static one. Make sure you add synchronized in front of it:

synchronized static method in java

NOTE: Since it is static we need to call it using the Class Name instead of using its instance.

If you run the above program now, you will get the same arrayed result:

result of calling a synchronized static methodIf your method is static, you could alternatively also make use of the synchronized block inside the method, by specifying the class name with “.class” extension like this:

synchronized block inside static methodIt will also give you the same result:

[First call] 
[Hey] 
[What up?]

Synchronization Resulting in Deadlock

There might arise a situation wherein one thread is waiting for another to release the object lock while the other one is waiting for the first one to do the same. There could be many threads for that to matter, all waiting. The program doesn’t go anywhere and it gets perennially stranded until of course you do something to fix it.

NOTE: You can come out of the deadlock by pressing Ctrl + C, or if working in an IDE choose to terminate it by clicking on the Red button on your console.

Deadlock Example

Here’s an example that will give you a lot more clarity on Deadlock in Java:

Let’s say there are two classes named Fire and Water both having their own run methods.

This is the first class Water with run() method using synchronized to lock String.class and then later locking Integer Class in the same method.

Water class run example in java

Here’s another Class called Fire with run() method using the same in a vice versa pattern:

Fire class run method in java

Here’s our main application method trying to call run methods using start() in their respective threads.

main method to call threads

Now in a multithreaded environment, threads have this habit of calling the start() method without waiting for the other to finish its execution. If you make one synchronized, one thread would then acquire a lock and finish its execution before moving on to the second thread and so on.

But since in our example above we have used synchronized against Integer.class and String.class these static classes will be locked until the lock is released on either of them. You see when Water will put a lock on String.class, and move on to lock Integer.class, the latter would already have been locked by Fire, and would itself be waiting for Water to release lock from String.class. This would create a deadlock situation.

Running the above will give you an inconsistent result:

Locking String Class
Locking Integer Class 

Locking String Class 

Locking Integer Class

Again the result might differ based upon your CPU processing time.

Volatile in Java

Similar to synchronized we have something called volatile keyword in Java that can be used to make your program stay thread safe, which means your method or class instance can be used by multiple threads simultaneously without any issues.

Here the keyword to use is, you guessed right, volatile. Unlike synchronized we use volatile with a variable.

If you make a variable volatile, changes made on one thread variable will be immediately updated for other threads as well. Thus eliminating inconsistencies just as was the case for synchronized.

The value stored in a volatile variable is never cached. That means all the reads and writes will be taken care of by the main memory itself. You want that to happen if you don’t want other threads to catch an erroneous cached value.

While synchronized provides both atomicity and visibility, volatile doesn’t provide atomicity but takes care of visibility. That being said it is advisable to go for synchronized block instead.

Inter Thread Communication

Also popularly known across the Java community as cooperation, it is a mechanism via which synchronized threads communicate against each other. That being said it is a part of thread synchronization in Java too.

One thread is paused in its critical stage and is paused for another thread to enter the same stage. We achieve inter thread communication by using some methods of Object class. These are namely:

  1. wait()
  2. notify()
  3. notifyAll()

If you wish to get rid of the lock on your thread, you could easily do so by using the wait() method. It would wait then for some specified time, or for a notify() method, or a notifyAll() method to be called in order to acquire the lock once again. It must be called from a synchronized method only.

Notify state is nothing but a runnable state. So if you put any thread in notify() it will become ready for execution. When there are many threads waiting, only one is chosen for execution. Any random thread will be picked.

Notify All will wake up all the threads in your program executing them.

NOTE: Remember if you are using inter thread communication make sure you use it for synchronized methods or inside its block, otherwise you get an IllegalMonitorStateException.

Wait and Notify Example

Also wait() and notify() must be called on the same object. If you don’t do that JVM wouldn’t understand where notify() should lead to, and your first thread will not be reached again.

Here, an example would help:

notify example in java thread in main classWe have a thread here in main class which is set to execute after 2 seconds, meaning the one thread in our run() method will be the first to execute. We have made use of synchronized block in order to test this.

Here’s that run() method flaunting its thread:

fire class run method in java

You can see start() method will take the control directly to run() here. But as soon as it prints the sysout stuff, it would release the lock with wait() allowing your program’s other thread to take control. It will go back and run the smaller loop first and on noticing the notify() method will run back to give the control to the previously paused thread. The rest of the execution will then follow.

Here’s how the result would appear like:

It's a big loop. Leaving it stranded...
1
2
3
4
and returning...
0
1
2
3
4
5
6
7
8
9

If there are many threads you can make use of notifyAll() instead of notify() to execute all other threads.

How do you interrupt a waiting or sleeping thread?

The question has its answer. You do that via interrupt method.

Interrupt() method is used to break a thread and head straight to the InterruptedException section of the wait() or sleep() method.

It is quite safe to use coz even if you use interrupt() when your threads are not in wait or sleep mode, it will simply mark the interrupted flag as true.

There are two other boolean methods from the Thread class namely interrupted() and isInterrupted() that can be used to check the status of the Interrupted flag for true or false.

We will see how interrupt() works here with an example.

I have simply added the interrupt() method below the sleep() method in the above program:

thread interrupt example in java

Now if you will run the program when it will reach this code to run the bigger loop, it will get interrupted to display what you have caught in the exception box:

It's a big loop. Leaving it stranded...
1
2
3
4
and returning...
0
Oh no! The thread was interrupted
But a thread's gotta do what it's gotta do

NOTE: The thread will continue to execute the rest of the code by displaying the caught exception. And that’s why the next code outside the try catch block was executed.

Reentrancy

That takes us to the final topic in synchronization in Java.

There is a concept called reentrancy in Java which means exactly what its moniker suggests. A thread holding a lock tries to re-enter the lock without releasing it. So if there is a synchronized method that you are dealing with, your thread has already acquired a lock on it. Now if you call the method again, the lock wouldn’t be released, rather stay with it. This is called reentrancy.

A simple example to explain this would be:

reentrancy in java example

Our main method has the following simple code:

 Thread t1 = new Fire();
 t1.start();

You can see that your thread has already acquired the lock using fly() method and yet using synchronized(this) it tries to continue acquiring the lock even after it has been successfully acquired. This is nothing but reentrance.

Also, remember a thread doesn’t deadlock against itself. For it to deadlock you need another thread, and a situation that has one thread waiting for the other which in turn waits for the previous one.

You could use it in special case scenarios where there is interruptible lock waits scenario, where you need your interrupted thread to resume again.

There is also a ReentrantLock variable available as part of java.util.concurrent.locks that you could use to achieve reentrancy.

With that concludes our chapter on synchronization in java. I think we have covered everything important that was a part of multithreading.

Phew!

Scottshak

Poet. Author. Blogger. Screenwriter. Director. Editor. Software Engineer. Author of "Songs of a Ruin" and proud owner of four websites and two production houses. Also, one of the geekiest Test Automation Engineers based in Ahmedabad.

You may also like...

2 Responses

  1. June 14, 2017

    […] in Java topic isn’t over yet. There is another crucial topic called Synchronization which we will see in the next […]

  2. September 4, 2017

    […] The StringBuilder in Java Class is exactly the same as StringBuffer. The only difference being StringBuffer is synchronized while StringBuilder in Java in unsynchronized. Forgotten the concept of synchronization already, nothing wrong with going back to learn what synchronization is all about. […]

Leave a Reply