Concurrency problems are most common problems among multi-threaded applications. If one single thread is executing, it can gracefully get access to the resources and complete its execution. The problem arises when multiple threads competing with each other to get hold of resources. Due to this variety of problems can occur like inconsistent data, dead lock situations etc. Java mitigates these problems by synchronizing resource access so that single thread get to access resources and releases the resource for the next thread to process. This process is known as “synchronization” and we achieve synchronization using keyword “synchronized”.
The “synchronized” keyword can be used in two contexts:
- In methods by defining required methods as synchronized
- By making block of code synchronized
Synchronization works by using locks. If any object has synchronized method code, then object will also contain a built-in lock. When any thread first gets into the synchronized method, that thread acquires the lock associated with the object. We can also call object lock as monitor. Since each object has only one lock, if any thread acquires the lock, no other thread cannot acquire the lock until the first thread releases the lock. This ensures that no other thread enters into synchronized method code thus preventing from inconsistent data.
The following are few rules with respect to synchronized keyword.
- Only methods and block of code can be synchronized, making variables or classes synchronized results in compilation error.
- Each object is associated with one and only one lock.
- If any thread’s sleep() method is called, the thread will go to sleep to sleep by keeping its acquired object lock. It doesn’t release the lock.
- A thread can acquire multiple locks belonging to different objects. But each object contains only one lock.
Using synchronized in methods
The following code snippet makes debitFromAccount method synchronized.
public synchronized boolean debitFromAccount(int accountId, double amount) {
// business logic to debit funds from account
}
As we marked above method synchronized, only one thread which has the object lock can execute this method and perform transaction. Other threads are in waiting state until the first thread releases the lock.
Using synchronized in block of code
Since synchronizing controls multiple thread accessing resources, this indeed comes with performance penalties. So instead of synchronizing entire method, we can synchronize a block of code as shown below. We can call this block of code as synchronized block.
class Account {
public boolean debitFromAccount(int accountId, double amount) {
// code that needs to be executed in non-synchronized context.
synchronized(this) {
// business logic to debit funds from account
}
}
}
As we see in above code snippet, instead of synchronizing entire method, we synchronized the block of code which needs to be executed in synchronized context. Also, the above code is acquiring lock on the current instance.
When thread is executing synchronized methods, the lock will be acquired on the object whose method is being executed. On the other hand, when the thread is executing block of code, we specify which object’s lock needs to be acquired. The advantage of synchronizing block of code is, we can also specify other third-party objects as well, so that thread will acquire locks on these objects.
How locks are acquired on static methods
Static methods can also be synchronized. Since there is no object in the static context, also our data is directly associated with class, the lock needs to be acquired on the entire class itself. In the case of static synchronized methods, the thread will acquire the lock on the java.lang.Class instance which is representing the Class.
- Top 45 Fresher Java Interview Questions - March 9, 2023
- 25 Free Practice Questions – GCP Certified Professional Cloud Architect - December 3, 2021
- 30 Free Questions – Google Cloud Certified Digital Leader Certification Exam - November 24, 2021
- 4 Types of Google Cloud Support Options for You - November 23, 2021
- APACHE STORM (2.2.0) – A Complete Guide - November 22, 2021
- Data Mining Vs Big Data – Find out the Best Differences - November 18, 2021
- Understanding MapReduce in Hadoop – Know how to get started - November 15, 2021
- What is Data Visualization? - October 22, 2021