pattern is definitely the easiest pattern of all the patterns but trust me, many of us are doing wrong. So let’s find out more about this pattern. Singleton design We all know the motivation of using Singleton pattern. It’s a pattern which allows us to have only a single instance of the object throughout the life-cycle of the application. Why would that be important? Because first, you don’t want to create more than one heavy resource consuming objects when you really want only one. Second, sometimes, not only creating more than one instance is costly, it can take you to inconsistent state. For example, you wouldn’t want to have multiple database objects because changes in one, may make others inconsistent. But now you might be thinking, if I just need one object and I want to access it from anywhere, why can’t I make it a global-variable? The answer is, yes, you can make it a global variable but what if that object creation requires heavy resource usage? Global variables might be created just when you application starts. You wouldn’t want too much of startup time for your Android app, right? These small things are easily noticeable in mobile world. To prevent this, we make use of lazy-loading, which means, create the object when it is needed. We’ll see that in a second. only Now that we are clear why we want a singleton object, let’s see what should be the characteristics of a Singleton object. A singleton class shouldn’t allow other classes to instantiate it. That means, no class should be able to do at all. How do we prevent this? This one is simple. Just make the constructor of the singleton class . This simple step makes sure that the object won’t be instantiated anywhere…except within the same class (private constructors can be called from the same class — This is true for private methods and fields too). Below is a simple example in Kotlin of a class with private constructors. new Singleton() private Singleton () class private constructor 2. A Singleton class should be accessible to the class: Even though we have restricted instantiation of the Singleton class, we can still have the access to that kind of object. This is by making a static method, which returns the Singleton object. In the below example, we have made a static method which checks if the instance is null. If so, it will instantiate a new object and assign it to the variable, which will be returned on subsequent calls to the method. INSTANCE getInstance Singleton (){ class private constructor **companion object** { **private var INSTANCE**: Singleton ? = **null fun** getInstance(): Singleton{ **if**(**INSTANCE** \== **null**){ **INSTANCE** \= Singleton() } **return INSTANCE**!! } } } Most of the people who implement singleton pattern get the above two things right. But the problem with the above code is that it produce more than one instance of your Singleton class in a multi-threaded environment. may getInstance(): Singleton{ ( == ){// <--- Imagine Thread 2 is here fun if INSTANCE null **INSTANCE** \= Singleton() // <--- Imagine Thread 1 is here } ... In the above code, both and will produce two distinct objects, defeating the purpose of a singleton class. This can be catastrophic to your application and might be difficult to debug also because as with other multi-threaded issues, they only happen in circumstances. Thread 1 Thread 2 some So an easy and no-brainier fix would be to just execute the code within a lock. That would go like this: synchronized getInstance(): Singleton { ( ) ( == ){ = Singleton()} !! } fun synchronized this {if INSTANCE null INSTANCE return INSTANCE } The above code will solve the case of creation of multiple instances but it may pose a performance problem. This means, even after correctly instantiating a singleton object, the subsequent access to it will be synchronized, which is not necessary. There is no issue in reading an object in a multi-threaded environment. A good ball park metric would be to consider that any block under synchronized code-block, will slow down the execution of that block by . If you are “OK” with this cost and you don’t need to access that singleton object too often, you can stop here. But if you do need to access it multiple times, it would help if you optimize it. a factor of 100 To optimize it, let’s think what we actually need to optimize. We need to optimize only the object creation flow, not the reading of the object flow. After the variable is created, synchronizing the flow is totally an unneeded overhead. INSTANCE An easy fix here would be to create the object eagerly, than lazily. Here’s how would it look like: Singleton (){ { = Singleton() getInstance(): Singleton { }}} class private constructor companion object val INSTANCE fun return INSTANCE In the above case, JVM will make sure that any thread access the variable after it has been created. But then again, as we discussed, it make add up to your startup time where you are creating an object even thought you’d need to later or won’t need it ever. INSTANCE So we will now take a look at “double-checked locking” which can help us overcome all the above issues which we’ve been talking about. In double-check locking, we’ll first see if the object is created or not, if not, then only we will apply synchronization. {@Volatile : Singleton ? = getInstance(): Singleton { ( == ){ ( ) = Singleton() } !!}} companion object private var INSTANCE nullfun if INSTANCE null synchronized this {INSTANCE } return INSTANCE As you can see, we are only applying synchronization during the object instantiation phase. You might be thinking, what is that annotation doing there. It’s the same as keyword in Java. As you know, each thread has its copy of variables in its stack and all the accessible values are copied to its stack when the thread is created. Adding a keyword is like an announcement that says “The value of this variable might change in some other thread” Adding makes sure that the value of variable is refreshed. Otherwise, it may so happen that, that thread never updates its local cache. @Volatile volatile volatile volatile As a final refactor, I’d like to make a small change and leverage Kotlin’s language construct. I really don’t like the screaming in the return statement. !! {@Volatile : Singleton ? = getInstance(): Singleton { ?: ( ) Singleton(). = }} companion object private var INSTANCE nullfun return INSTANCE synchronized this { also {INSTANCE it}} So there you have it, the perfect way to may a Singleton. Your implementation may differ based on other considerations like your application not running in a multi-threaded environment or you are fine with the performance cost of putting synchronize keyword over the entire method. Thanks for reading it. If you find it interesting, feel free to put a clap(or ten?) on it and share it. If you’d like to read more articles like this, you can follow me. Here are few other articles that might interest you: Learn in 2 minutes: @JvmOverloads in Kotlin Daily Kotlin: Static methods RxJava — Flowables — What, when and how to use it? RxJava — Schedulers — What, when and how to use it?