There are two null checks inside the getInstance() method because it is possible for the instance variable to be null even after the synchronized block. This can happen if two threads enter the synchronized block at the same time. The first thread will check if the instance variable is null, and if it is, it will create a new instance of the Singleton class. However, before the first thread can assign the new instance to the instance variable, the second thread may also enter the synchronized block and check if the instance variable is null. If it is, the second thread will also create a new instance of the Singleton class. This would result in two instances of the Singleton class being created, which is not desired.
as its singleton, this is mix of synchronization and lazy loading, I explained how its lazy loading where we make object on first call of getInstance()