1. Introduction
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’.
2. Usage
The synchronized keyword can be used on different levels:
- Instance methods
- Static methods
- Code blocks
When we use a synchronized block, internally Java uses a monitor also known as monitor lock or intrinsic lock, to provide synchronization. These monitors are bound to an object, thus all synchronized blocks of the same object can have only one thread executing them at the same time.
2.1 synchronized instantce method
Simply add the synchronized keyword in the method declaration to make the method synchronized:
public synchronized void synchronisedCalculate() {
setSum(getSum() + 1);
}
Instance methods are synchronized over the instance of the class owning the method. Which means only one thread per instance of the class can execute this method. |
2.2 synchronized static method
public static synchronized void synchronisedCalculate() {
setSum(getSum() + 1);
}
These methods are synchronized on the Class object associated with the class and since only one Class object exists per JVM per class, only one thread can execute inside a static synchronized method per class, irrespective of the number of instances it has. |
2.3 synchronized blocks within methods
Sometimes we do not want to synchronize the entire method but only some instructions within it. This can be achieved by applying synchronized to a block:
public void performSynchrinisedTask() {
synchronized (this) {
setCount(getCount()+1);
}
}
Notice, that we passed a parameter this to the synchronized block. This is the monitor object, the code inside the block get synchronized on the monitor object. Simply put, only one thread per monitor object can execute inside that block of code. |
In case the method is static, we would pass class name in place of the object reference. And the class would be a monitor for synchronization of the block:
public static void performStaticSyncTask(){
synchronized (SynchronisedBlocks.class) {
setStaticCount(getStaticCount() + 1);
}
}