Double checked Locking in Singleton Design pattern | Java Interview Questions | Code Decode

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys welcome to code Decor today in this video we are going to see what is double check locking of Singleton class what is a Singleton class how to create it how to prevent the breaking of Singleton class what a ways to break it every possible interview questions around the Singleton classes so let's get started please like share and subscribe to support us and we are setting a like Target of 500 likes so initially we have already covered in the previous video what the single written class and which scenario it will break so we will quickly go ahead and Implement a Singleton class keeping three things in mind firstly create a private static single till instance secondly if the instance is private how will you access it to access this private instance you need a method which will return you the instance of the same object check whether it is null if it is null then create a new object with new keyword else written the same object so that you get only single instance everywhere in the whole program so Singleton is have a single instance all over the application and not to create a new one and third and very important part to create a private Constructor so that nobody can create your instance with a new keyword so let's go ahead and implement it I'll create a new class named a Singleton let's implement the three points first point is to have a private static instance of the same class private static instance of the same class I'll name the instances as instance only and secondly I have to create its Constructor private so that nobody can create with a new keyword if they create a new keyword instance with a new keyword then you will have different instances of the same class at different places so Singleton Constructor must be private secondly now if the Constructor is private if your instance is private how will anybody create even a single instance of your class so for that to access an instance of this class you need a method that will be a public method which will return you a Singleton object get instance say and it will check if your instance is null only in that case it will create a new object it will assign it to this with a new keyword else if the instance is not null return the same instance so this is how we have implemented our Singleton class just by keeping three things in mind create a private variable create a private Constructor and create a public method which will return the instance of the same class and but it will check whether if it is null if it is null don't then only create a new variable else written the same now to check whether this is purely truly single till you should make sure that the hash code of the object being printed by this method or return by this method is same so let's quickly go and create a new class which is main class for us we'll create a main method here and let's create Singleton instance now you cannot create with a new one why it says change the visibility of single till 2 package because we have created it private it is not able to access the Constructor if you change it it will become the default package all the public one and then you can easily create an object with this but it will break our Singleton pattern so let's not do that let's comment it as of now and let's try to get the instance from the get instance method that we have created the get instance method must be public static so that we can call it without the object get instance and then print the instance once hash code similarly create second instance also and print its hash code also you can see this in a hash code of both the objects are same this proves that this particular method will always give you single instance when all when called multiple types this is the opposite case when you have created with a new keyword so if if let's remove this private let's ask them to create with the new single Constructor every time and now let's try to print it it shows you a different hash code that means if you do it with a new keyword you will always get a unique object with a different hash code so instance one is not equals to instance 2 there are two different instances in all possible ways but if you use this method by not using the new keyword but if you use this particular way the get instance that we have created keeping the Constructor private then you get a pure Singleton instance with the same hash code always so that's how we have implemented the Singleton one by looking at this line of course this 15 or 16 lines of code can you see any possibility that it can be broken is there any possibility that this Singleton instance might have the different hash codes like we had in with a new keyword with using the Constructor so yes there is a chance there is one scenario where the Singleton creation that you have done will break and that scenario is in multi-threaded moment the above code will create multiple instances of Singleton class which will break your Singleton concept all together if called by one or more thread in parallel known as in multi-threading environment so now consider a situation that two threats are working upon your Singleton class they both are trying to create an instance the get instance is called it checks the two thread is simultaneously at line number 10 they check if instance is null so for the first time go to the thread tree 1 and T2 C is okay my instance is null so they both go inside this and creates a new Singleton object and that scenario you will have two different Singleton objects with different hash codes because at the same time if true thread simultaneously checks the line number 10 that is instance is null they both will find it null then they both will create a new instance though this is a border in Edge case scenario but this is a scenario when two threads simultaneously checks when the instance is null then they both will create a new instance and your Singleton will break so now this is a problem so what is the solution to prevent the breaking of this particular get instance method scenario if this is causing problem let's make it synchronized if this is the case we've made this method synchronized then when two threads T1 and T2 try to access this method instance get instance method only one thread can check if instance is null if instance is null only one thread T1 can create a new Singleton and by the whole time it is doing its task T2 will wait but don't you think this is performance being getting impacted by making the whole method synchronized in the thread multi-theaded environment we have seen we should only make the synchronization for those line of code which are creating a problem so from line number nine to line number 14 which code is creating problem when simultaneously being accessed by two threads so line number 10 is the line which is causing problem when accessed by two threads simultaneously so T1 and T2 checks if both are null it will both create the new instance which is a problem so only these line of code is a problem so why to synchronize whole method this is a performance impact right so one primary solution is to make the get instance method synchronized though it is thread safe and it solves your multiple instance issues yes it too but it is not very efficient why because you need to build the cost of synchronization every time your call to this method goes so okay fine first time your thread even in T2 is trying to access it so T1 will wait and check whether instance is love yes it is null it will create a new instance by the time T2 will wait now third time three T three T four everybody will come and try to create an instance but only the application start T1 has already created a new instance so every time P4 T5 T6 will always never get your instances null but still your T3 T4 T5 T6 All have to go into this method one by one because it is synchronized though for all of them they will have them this particular condition failing simultaneously T3 T4 and T5 cannot exist this method though they are not going to touch critical section at any cost so if this is not going to be touched and still you are making it synchronized it is a performance impact and hence you need to bear the cost of synchronization every time you call this method while synchronization is needed only on the first time the first time when your application starts and your first hit creates the new instance with a new keyword after that none of the thread will be able to bypass this because the instance is already created in memory and they will directly run the line number 13. still every time because you have made it synchronized every time all the threads have to go one by one in this method and the whole impact will be on the performance so this brings us to the double check locking pattern where only critical section is locked let me first implement it implement this double checking for you in this if condition we will synchronize only the critical section and how to do that with a block so we are not synchronizing a method we are synchronizing a block of code now only in that particular code block we are going to again check whether it is null if it is null then only instantiate it with the new keyword and not here this particular critical section is now not in a method but in a in a code block the synchronized code block let me dry run this for you at first instance T1 and T2 simultaneously get to this method get instance it goes to line number 10 and see if the instance is null so T1 and T2 at the start of your application will get instances null so T1 and T2 will go to line number 11 simultaneously but only one thread out of T1 and T2 can get into the line number 12 and check whether it is null if it is null it will create an instance and then leave the code block synchronize block and then the second thread can get into the code block NCO okay now it is not null I can happily go out of the synchronized block I will happily ignore this if foundation and I'll return the existing instance that was created by thread table so this is how you have moved your whole method which was synchronized to just one synchronized block keeping any critical section in that particular synchronized block now why is it called double checking because if you can see we have the code redundancy if instance equals to null if instance equals to null so this is double checking first time it checks oh there can be a case multiple threads are checking it but only one instance is able to create a new instance because of the synchronized block only one thread is allowed to get into this again check whether it is really null if it is really null create a new instance if it is not null then happily go out of the synchronized block and return the instance now what was the advantage initially when you have made the whole method synchronized after the first time table has created your instances the fourth fifth time when P3 T4 T5 comes they also have to go one by one and check whether it is null for sure it is not going to be null so anyways they have to written the same instance so now with removing the synchronization on the method level now T3 T4 T5 simultaneously can check the line number 10 whether instance is null they will say no it is not L they all will return the same instance and hence no critical section is touched by two or three thirds simultaneously so that is the advantage of double checking locking pattern in single tip so here it is called double checking blocking because there are two checks for instance equals to null there are two checks for instance equals to null one without clocking and one with locking one without locking will make sure multiple threads can access it and one with locking will make sure only one instance can create an instance of Singleton class so here the intention is to reduce the synchronization first and improve the performance by only locking the critical section the code which creates the instance of a Singleton class the critical section was to check it and create an instance resource critical section only that two line of code block is written in the second pronounced code block now the first time goes into the synchronized block rest of the all calls the code is not synchronized and hence performance is increased in this implementation I've already told you the first time instance is created next time three simultaneously threads comes none of the none of them has to wait one by one to get into this method they all can check whether threading instances null they will say instances not null they all will written the same instance this 76cc d017 simultaneously without any code issues so on the service this method looks perfect right as you already need to pay the price of synchronized block only one time so this synchronized block will run only one time and a performance will be awesome as good as it was not at all synchronized because this block will run only once in the whole lifetime of the application and it looks perfect right but still if you can see this code is broken still multiple instances can be created even after doing all these two Singleton class now how it can be broken because you have not created your instance variable volatile so still your instance variable is not volatile now how what what is volatile in Java volatile keyword is used to Mark a variable being stored in the memory now currently it can be a case that multiple thread T1 and T to create the cache in their thread from from the main memory to the CPUs so multiple CPUs cores are there multiple threads can run on multiple CPU cores they could create their own caches of the instance so I'll give you an instance how still this can be broken T1 gets into this get instance method now T1 sees if instance is null for the first time yes it was null so it runs line number 11 and gets into the instance block the synchronized Block in size of instances now yes instance is null and hence Steven reaches here it was about to run line number 13 of creating the new instance with a new keyword but as soon as it was about to do that it was the CPU was taken from T1 given to T2 T1 has stored the state to run line number 13 and create a new Singleton keeping that state it it left the CPU now T2 came into picture it says in the main memory is there any instance created no it there is no instance created because any anything and everything done to that instance was in the CPU caching not in the main memory in the main memory instance is still null so T2 again gets into the synchronized Block in check if it is null yes in the main memory it was null it again creates a new instance and leave the CPU by creating one new instance of Singleton now T1 gets the CPU and it's it reads its last state the last state was it has just to run line number 13 and rest of its work is done so T1 runs the line number 31 again creates a new Singleton instance at that point when line number 13 is run by the T1 you will have two instances one that was created by T2 who snatched the CPU from T1 and Steven who has after getting the CPU back just ran the late latest state it was on and the latest date was at line number 13 it ran again and you have two instances for table and T2 it happened because T2 could not read the instance which was already half written by T1 that too in the caching so the old whole problem was because of the caching the threats that was caching the data that can be resolved using the volatile keyword which makes sure that the data is written to the memory and read from the memory so volatile keyword makes the variable as being stored in the memory that means every read will be from the main memory not from the cache and every write will be to the main memory and not to the cache so without a volatile modifier it was possible for another thread to see half initialized state of instance variable but volatile keyword guarantees the happen before relationship the happen before relationship came into picture only after Java 1.5 so what happened before relationship says for Java volatile all the right will happen before any read of the volatile keyword so first all the write will happen and then only any read will happen this is how you make a variable volatile okay so as soon as you make it volatile first all the write will be done and then only you can read it T2 was about to write a new single tier instance to this particular memory reference but T2 snatched the CPU from T1 now since T1 was about to write it now T2 cannot read this instance from the main memory and modify it because it says first all the right will happen and then only the t2 can read it so until T1 do not completely write it T2 cannot read it so all the right will happen before any read of the instance variable which is volatile this was not prior to Java 1.5 so a double check login was also broken so even before Java 1.5 there was no way to prevent your Singleton from breaking there are multiple ways more to prevent your Singleton break using the enums in many more ways we will discuss that in the second part of this video thank you
Info
Channel: Code Decode
Views: 19,721
Rating: undefined out of 5
Keywords: singleton double checked locking, double checked locking, singleton design pattern double lock, double checking in singleton, singleton code decode, code decode, java interview questions code decode, code decode singleton, code decode java interview questions, singleton design pattern in java interview questions, singleton design pattern code decode, singleton, double checked locking pattern, singleton double check
Id: p4UbfBRpke0
Channel Id: undefined
Length: 17min 52sec (1072 seconds)
Published: Tue Aug 09 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.