class SimpleSingleton {
private static SimpleSingleton sInstance;
private SimpleSingleton() {}
public static SimpleSingleton getInstance() {
if (sInstance == null) {
sInstance = new SimpleSingleton();
}
return sInstance;
}
}
class SimpleSingleton {
private static SimpleSingleton sInstance = new SimpleSingleton();
private SimpleSingleton() {}
public static SimpleSingleton getInstance() {
return sInstance;
}
}
public class Singleton {
private static final Object LOCK = new Object();
private static Singleton sInstance;
private Singleton() {}
public static Singleton getInstance() {
if (sInstance == null) {
syncronized(LOCK) {
sInstance = new Singleton();
}
}
return sInstance;
}
}
public class Singleton {
private static Singleton sInstance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (sInstance == null) {
sInstance = new Singleton();
}
return sInstance;
}
}
public enum Singleton {
INSTANCE;
}
Thread safe and lazy, but only for static fields.
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private final static Singleton sInstance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.sInstance;
}
}
Thread safe and lazy.
Volatile is necessary, but can cause perfomance problems(?), and doesn't work on JDK4 and lower.
public class Singleton {
private static volatile Singleton sInstance;
private Singleton() {}
public static Singleton getInstance() {
if (sInstance == null) {
synchronized (Singleton.class) {
if (sInstance == null) {
sInstance = new Singleton();
}
}
}
return sInstance;
}
}
Stolen from HERE.
Object level lock is mechanism when we want to synchronize a non-static method or non-static code block such that only one thread will be able to execute the code block on given instance of the class. This should always be done to make instance level data thread safe.
public class DemoClass
{
public synchronized void demoMethod() { ... }
}
public class DemoClass
{
public void demoMethod() {
synchronized (this) {
// Thread safe code.
}
}
}
public class DemoClass
{
private final Object lock = new Object();
public void demoMethod() {
synchronized (lock) {
//Thread safe code.
}
}
}
Class level lock prevents multiple threads to enter in synchronized block in any of all available instances of the class on runtime. This means if in runtime there are 100 instances of DemoClass, then only one thread will be able to execute demoMethod() in any one of instance at a time, and all other instances will be locked for other threads.
Class level locking should always be done to make static data thread safe. As we know that static keyword associate data of methods to class level, so use locking at static fields or methods to make it on class level.
public class DemoClass
{
// Method is static.
public synchronized static void demoMethod(){ ... }
}
public class DemoClass
{
public void demoMethod()
{
synchronized (DemoClass.class) {
// Thread safe code.
}
}
}
public class DemoClass
{
// Static object.
private final static Object lock = new Object();
public void demoMethod() {
synchronized (lock) {
// Thread safe code.
}
}
}
class Singleton private constructor() {
companion object {
@Volatile private var instance: Singleton? = null
fun getInstance() =
instance ?: synchronized(this) {
instance ?: Singleton().also { instance = it }
}
}
}
This is good to know, thank you for the information.