I just learnt my fourth design from the Head First Design Pattern book. Today, I learnt about the Singleton pattern.
According to Head First Design Patterns, the Singleton pattern is a pattern that is used to ensure a class has only one instance, and provides a global point of access to it.
For example, the singleton pattern can be implemented in Java like this
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
In order to ensure the Singleton
class only has one instance, It's constructor is marked as private. Singleton
has an API called getInstance()
.
The Singleton pattern seems like a very simple pattern but there are some gotchas you need to be aware of when it comes to using the Singleton pattern and multithreading. In a multithreaded code, it is possible to create multiple instances of the class above since multiple thread can have access to the getInstance
function at the same time.
There are many ways to fix this:
1: Refactor the code above to use synchronised keyword.
public class Singleton {
private volatile static Singleton instance;
private Singleton() {
}
public static synchronised Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
By adding the synchronised keyboard to the getInstance()
we are forcing every thread to wait it's turn before they enter the function. So only one thread can access the getInstance()
function.
2: Simply use the Object
keyword from Kotlin. Kotlin has the Singleton pattern built into the language with the Object
keyword.
object Singleton {
}
If you need to have on instance of a class, for example, loggers, analytics, crash reporting. You should use the Singleton pattern
Top comments (7)
For Selenium in Java I was using a singleton pattern to setup the WebDriver instance. Since switching to Kotlin, I was having issues with it working reliably with the object way. I was getting multiple browsers opened, which is contrary to the singleton pattern purpose.
How are you using this pattern with or without the object concept in Android?
Could it be that your code was getting called multiple times or in multiple threads? I'm not sure but I can imagine that with Selenium. You might want to search for "thread-safe singleton" in Kotlin when trying to fix it again, quite possible the
object
approach isn't by default, but I'm sure there's an easy fix.That makes a lot of sense. Thanks Cihat for the explanation. Although, kotlin
object
is actually thread safe. kotlinlang.org/docs/object-declara...That is what I thought, but if it is spinning up multiple threads, maybe that is why it is spinning up multiple browser instances. I’ll have to look into it again when I get time away from Android studies lol.
Ah that is a good point to make. It is possible I set it up with parallel running without thinking about it! Will do and thanks for the tip!
Oh, That's very weird. I don't know anything about Selenium. I've always used the object keyword whenever I need to use the Singleton pattern but you can try this. It should work.
Let me know if it does
If and when I get back to the project, I can try it! Thanks!