Buzz words in Multi-threading …..
In Multi-threading we usually confused between the
Volatile,Synchronized and Atomic
To clearly understand these words , you need to understand two scenarios which we facing in highly concurrent environments .
- visibility problem
- synchronization problem
1. visibility problem
Lets consider above scenario which causes an visibility problem between two threads in highly concurrent environments.
we have global variable status = true, while thread-1 starts some processing when the status = true
After some time when the thread-2 starts,status is updated with false then thread-1 is also stops processing. this is what usually we expected to be happen but In some highly concurrent environments it is not possible
if two threads works on two different cores, then status what you have updated by thread-2 in above scenario is does not reflect to the thread-1 because it is stored in local cache. This is called visibility problem between the two threads
To solve the above problem we need to use volatile keyword
public volatile boolean status = true ;
if you mention the volatile to the specific variable, what ever the modifications you will made by the every thread is written to the shared cache.
2. synchronization problem
In this scenario, it looks like single operation , it is not single operation
read →modify →write
we have the int value = 1 . when thread-1 runs starts running first then i=2 and later thread-2 runs then i = 3 .
In vice-versa if thread-2 starts first then also i=2 and later thread-1 then i=3.
But in highly concurrent environments , some times it does not work correctly
if JVM schedules the thread which is interdependent on each other
- thread 1 →read the value = 1 →committed to shared cache because value is volatile.
- thread 2 → read the value =1 →committed to shared cache because value is volatile
- thread 1 → update the value = 2 →committed to shared cache because value is volatile but thread-2 does not read from shared cache because read operation is already completed
- again thread 2 → update the value = 2 committed shared cache which is completely wrong.
This is synchronization problem ……..
To avoid the synchronization problem,we use Atomic variables or synchronized blocks for variables, for methods we use synchronized key word.
Use Case to understand synchronization problem:
- In above program I took ConcurrentHashMap consists Party Name as key and number of votes as a value.
- I took 5 threads and Each thread vote 1000 votes to each party , i.e means as per our expectation, after running all the threads each party must and should contains 5000 votes
- But I run these 5 threads in Multi-threading Environment, Due to this I got an different output as shown as below
we need to use atomic variables to solve the above problem
solution :
Difference between the volatile and atomic
- volatile is suitable only for read →write cases
- atomic variables are used for read →update →write cases
3. Use Case to avoid visibility and synchronization problem with singleton Implementation
- In high concurrent environment there is a possibility that two threads will enter
2. JIT compiler rearrange the byte code in a way that reference to the getInstance() set before the constructor has finished it’s execution.this means there is a chance that,method getInstance() returns the object which is not completely initialized.
Java 5 . for instance variables, the variables which are marked as volatile are only visible to the other threads when the constructor of the object initialized completely
Conclusion ……
when we are using global variables in multi-threaded environments , to avoid visibility and synchronization problems we need to use in below mentioned way
- volatile →flags
- Atomic Variables →counters
- Atomic References → Cache
- synchronization block with volatile →variable is global and Need visibility to every thread what is the current state of the object.