Synchronized Keyword in Java
Overview
Thread is the path opted for during the execution of a program. In a multi-threaded environment in Java, More than one thread can access the same resource. Synchronization is necessary for locking the access of resources or data to a single thread when multiple threads require the same resource. The synchronized keyword is marked both in instance and static methods. There are two types of synchronization - Process synchronization and thread synchronization. Process synchronization coordinates the sharing of resources among two or more processes. Thread synchronization coordinates the sharing of resources among two or more threads. Its salient features include locking the resources to a thread and preventing the program statement from getting reordered.
What is Synchronization?
Thread is the path taken by a program during its execution. Each program has at least one thread provided by the Java Virtual Machine at the start of its execution. In a multi-threaded environment in Java, More than one thread can access the same resource. For example, multiple threads can read or write to the same file. The absence of synchronization between the two or more threads that have the write access to the same file may lead to the corruption of the data written to the file.
In the Java Virtual Machine (JVM), every thread has its local copy of variables stored in a stack whose actual value can change by the modification done by some other thread. The changes may or may not get updated in another thread's local copy, which may cause erroneous execution of programs and non-deterministic behavior.
It is where the synchronized keyword in java comes into action. The synchronized keyword acts as a lock to the resources that help us avoid issues faced during the execution of programs. It sets better communication between threads to make the synchronized resources accessible to the threads one by one. The synchronized resource gets distributed to the other threads as soon as it gets free.
We can use synchronized keywords in different ways inside a code:
- The synchronized keyword can be used with a method as the given syntax:
The synchronized method helps us to prevent the interference of the thread. The synchronized method performs the read or writes operation to an object's field that is visible to multiple threads. If the synchronized method is under execution by one thread, other threads will have to wait to invoke the synchronized method on the same object until the previous one is done with it.
Example of Synchronized Method
Let's look at an example of more than one thread accessing the same method without synchronization.
Output:
In the above example, two or more students can access the same method at a time which may cause a collision. The synchronized method synchronizes the line accessed by multiple threads and prevents collision.
Let's transform the above code to get synchronized access to the getLine() method.
Output:
In the above example, two or more students can access the same method but one at a time.
- It can be used as a synchronized block that looks like:
We synchronize a block when we don't need all the lines of code inside a method to be executed. It helps us synchronize only the required part that contains the instructions. Let's assume that there are 100 lines of code in a method out of which only 20 lines are to be synchronized. In that case, those 20 lines are inside a synchronized block.
Example of a Synchronized Block
Output:
In the above example, MyThread2 gets executed first as the resource lies with it. Upon its execution, the resources transfer to MyThread1, which prints the table of 5.
How Does Synchronization Work in the JVM?
Every object in the synchronized block gets placed inside a lock. A lock is an internal monitor that checks synchronization. Each thread acquires the lock while entering the synchronized block or method. Only one thread acquiring the lock can execute the code in that block. Any other thread trying to access the synchronized block has to wait until the complete block execution of the current thread. Once a thread completes execution and exits, the lock gets released automatically and transferred to the waiting thread. The thread then acquires the lock and enters the synchronized block. The lock gets acquired in three different ways:
- In a synchronized block, the lock gets acquired by the object specified in the parenthesis after the synchronized keyword.
- In a synchronized static method, the lock gets acquired by the object with the .class.
- In a synchronized instance method, the lock gets acquired by this instance of the class.
Synchronized keywords in java can mark four different types of blocks. They are:
- Synchronized instance methods
- Synchronized static methods
- The synchronized block inside Instance Methods
- The synchronized block inside Static Methods
Syntax
The following is the syntax of the synchronized block in java.
Types of Synchronization in Java
We study two types of synchronization in java. They are as follows:
- Process Synchronization
- Thread Synchronization
Process Synchronization
Process synchronization coordinates the distribution of resources among two or more processes such that no two process shares the same resource or data. It is present in a multi-process system where more than one process requires the same share of resources or data at a time. Changes made by a process don't get updated in the local storage of the other process while accessing the same shared data. It is when synchronization is needed to synchronize the process with each other that avoid inconsistency of shared data. Let's see it through an example. A process P1 updates the data at some address in the memory. Another process P2 reads the data from the same address in the memory simultaneously. There is a high chance that the data read by process P2 may not be correct.
There are four sections of a program in OS. They are as follows:
- Entry section
- Critical Section
- Exit Section
- Remainder Section
Thread Synchronization
The sharing of the same resource by two or more threads is known as thread synchronization. Thread is the path or direction chosen by a program during execution. Generally, all processes have multiple threads, and a single thread may also contain many threads. The process schedules all the threads for sharing the same resource.
Example of Synchronized in Java
- Synchronized Instance Methods - Each object in a synchronized block with instance methods has its synchronized method. For each object, only one thread can execute inside a method. If there are multiple threads, only one of them gets executed.
Synchronized Instance Methods synchronize over the instance of a class that owns it. Thus, it can get executed by only one thread per instance of a class.
- Synchronized Static Methods - Static methods can be marked as synchronized in the same way as for instance methods. Let's look at an example of Synchronized Static Methods in java.
Synchronized Static Methods synchronize on the object associated with the class. In a JVM in Java, only a single class object can exist in each class. Thus, a synchronized static method can execute only one thread per class, regardless of the number of instances.
- The synchronized block inside Instance Methods - We might encounter cases when there is no need to synchronize the whole method. In such cases, a particular block inside a method can synchronize. Let's understand synchronized blocks inside Instance Methods better with an example.
In the above example, the keyword is passed as a parameter to the synchronized block. It works as the monitor object that helps synchronize the code inside the block. Each monitor object can execute only one thread inside a code block.
- The synchronized block inside Static Methods Synchronized blocks can also be inside static methods. The following example shows us how a synchronized block inside the static method operates in java.
In this case, the class name gets passed as a parameter in place of the monitor object, which helps to monitor the block synchronization.
Need for the Synchronized Keyword in java
The synchronized keyword in java helps us reduce the concurrency when we share the same resource between multiple threads or processes. The fundamental features of the synchronized keyword are:
- The synchronized keyword locks the resources to a thread so that no other thread can access it at a time.
- The synchronized keyword prevents the program statement from getting reordered.
- The synchronized keyword ensures the locking and unlocking of threads before and after getting inside the synchronized block. The thread reads the data from the main memory after receiving the lock. After completing the read operation, it flushes the write operation to release the lock.
Important Point of Synchronized Keyword in Java
- The synchronized keyword locks a single thread with the shared data so that no other thread can access it.
- The synchronized keyword can only synchronize a block or a method.
- A thread getting inside a synchronized block acquires the lock and releases it while leaving.
- We may get a NullPointerException while using a null object in the synchronized block.
- Not more than one JVM can provide access to a shared resource while using the synchronized keyword in Java.
- The slow working of the synchronized keyword may lead to poor performance of the system.
- The synchronized block is preferred more than the synchronized method in java.
- Improper implementation of synchronization in our code may lead to deadlock or starvation.
- Synchronized keywords are not allowed with constructors and variables in Java as it is considered illegal.
- Some methods like wait(), notify(), and notifyAll() defined in the Object class can be used while executing synchronization in Java.
Conclusion
- Synchronization is necessary for locking the access of resources or data to a single thread when multiple threads require the same resource.
- The synchronized keyword is marked both in instance and static methods.
- There are two types of synchronization - Process synchronization and thread synchronization.
- Process synchronization coordinates the sharing of resources among two or more processes.
- Thread synchronization coordinates the sharing of resources among two or more threads.
- Its salient features include locking the resources to a thread and preventing the program statement from getting reordered.