Double-checked Locking (DCL) and how to fix it - java

I was reading an article about Double-checked Locking. The problem discussed is as follows:
public class MyFactory {
private static MyFactory instance;
public static synchronized MyFactory getInstance() {
if (instance == null)
instance = new MyFactory();
return instance;
}
private MyFactory() {}
}
One of the suggested ways how to avoid synchronization on every getInstance() call is to use the class loader:
public class MyFactory {
private static final MyFactory instance;
static {
try {
instance = new MyFactory();
} catch (IOException e) {
throw new RuntimeException("Darn, an error's occurred!", e);
}
}
public static MyFactory getInstance() {
return instance;
}
private MyFactory() throws IOException {
// read configuration files...
}
}
Author says: "... the JVM ensures that this static initialisation code is called exactly once, when the class is first referred to and loaded." Which I totally agree. But I don't understand the follows: "Using the class loader is generally my preferred way of dealing with lazy static initialisation."
Is the second code snippet a lazy static initialisation?

It is not lazy. This is lazy (using class loader):
public class Singleton {
public static class SingletonHolder {
public static final Singleton HOLDER_INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.HOLDER_INSTANCE;
}
}

Not exactly. The initialization happens when MyFactory class was loaded, not when getInstance() was called. If you want to initialize the instance when the method was called, you can use a holder class.
public class MyFactory {
private static final class Holder {
private static final MyFactory instance = new MyFactory();
}
public static MyFactory getInstance() {
return Holder.instance;
}
}

Playing with Double-checked locking is like playing with fire. There are many ways one can get it wrong.
The purpose of Double-checked locking idiom is to avoid unnecessary synchronization. Thus your first code snippet doesn't fit into the category.
Coming to your second code snippet, if the singleton you are creating is static, then there is a compact solution in which you can define the singleton as a static field in a separate class and not in the same class.
class MyFactorySingleton {
static MyFactory singleton = new MyFactory();
}
This semantics of Java guarantees that the field will not be initialized until the field is referenced, and that any thread which accesses the field will see all of the writes resulting from initializing that field.
But from JDK5 and later, Java has started supporting volatile semantics which says that
the value of a variable which is declared volatile will never be
cached thread-locally. All reads and writes will go straight to "main
memory". Access to the variable acts as though it is enclosed in a
synchronized block, synchronized on itself.
So, a some what fool proof design for a Double-checked looking should look like this:
class MyFactory {
private volatile MyFactory instance = null;
public MyFactory getInstance() {
if(instance == null) {
synchronized(MyFactory.class) {
if(instance == null) {
instance = new MyFactory();
}
}
}
return instance;
}
}
Prof. Joshua Bloch and his co-authors explains how Double-checked locking can go wrong in this article. It is worth reading this.

Related

Singleton class in Android application using synchronized initalizer

I need a single instance of one class to be used across my whole Android application.
I am using the following code to achieve this and I want to be sure that doing it like this is correct, thread-safe and doesn't have an impact on performance.
public class MyClass {
private static MyClass instance;
public static synchronized MyClass getInstance() {
MyClass myClass;
synchronized (MyClass.class) {
if (instance == null) {
instance = new MyClass();
}
myClass = instance;
}
return myClass;
}
}
Whenever I need an instance of MyClass in the application, I call:
MyClass.getInstance();
So, I want ot be sure I'm not doing something wrong here, that this approach won't cause any problems down the line of development and if there are any better alternatives.
I think you don't need a second synchronized inside getInstance method and also you need to make MyClass constructor to be private.
public class Singleton {
private static Singleton INSTANCE = null;
// other instance variables can be here
private Singleton() {};
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}

Singleton with or without holder = lazy vs eager initialisation?

Is this correct:
Using a singleton with a holder gives lazy initialisation because the class SingletonHolder is only initialised when Singleton.getInstance() is run. This relies on SingletonHolder only ever being referenced inside Singleton.getInstance(). It's thread safe because the class loader takes care of synchronisation.
Using a singleton without the holder is eager initialisation because as soon as Java comes across code that references Singleton, all its static fields are resolved. It's also thread safe because the class loader takes care of synchronisation.
Singleton with a holder.
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
private Singleton(){ }
}
Singleton without a holder.
public class Singleton{
private static final Singleton INSTANCE = new Singleton();
public static Singleton getInstance(){
return INSTANCE;
}
private Singleton(){ }
}
Update in response to #jan's suggestion that this is a duplicate of What is an efficient way to implement a singleton pattern in Java?. I disagree. I am not asking what is the best way to do it: I am only asking what makes these two specific implementations lazy vs eager loading. Answers like xyz's broadly address lazy vs eager, but not by contrasting the two examples I was trying to examine (or with the same keywords which is why it never came up in my initial searches).
In response to #Sriram, here is my test to prove which is eager vs lazy loading.
Lazy loading with a holder
public class Singleton {
private static class SingletonHolder {
static {
System.out.println("In SingletonHolder static block.");
}
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
System.out.println("In getInstance().");
return SingletonHolder.INSTANCE;
}
private Singleton() {
System.out.println("In constructor.");
}
private void doSomething() {
System.out.println("Singleton working.");
}
public static void main(String[] args) {
System.out.println("Start of main.");
Singleton.getInstance().doSomething();
System.out.println("End of main.");
}
}
The output shows that the main method starts before getInstance() is called, thus lazily loaded.
Start of main.
In getInstance().
In SingletonHolder static block.
In constructor.
Singleton working.
End of main.
Eager loading without a holder
public class Singleton {
static {
System.out.println("In Singleton static block.");
}
private static final Singleton INSTANCE = new Singleton();
public static Singleton getInstance() {
System.out.println("In getInstance().");
return INSTANCE;
}
private Singleton() {
System.out.println("In constructor.");
}
private void doSomething() {
System.out.println("Singleton working.");
}
public static void main(String[] args) {
System.out.println("Start of main.");
Singleton.getInstance().doSomething();
System.out.println("End of main.");
}
}
The output shows that the main method starts after the getInstance() method is called, thus eagerly loaded.
In Singleton static block.
In constructor.
Start of main.
In getInstance().
Singleton working.
End of main.

Singleton Pattern time of object instantiation

This may seem like a silly question, but I was wandering when creating a class following the singleton pattern, at what point is the object instantiated?
e.g. private static SingleObject instance = new SingleObject();
with the method getInstance() defined by:
public static SingleObject getInstance(){
return instance;
}
So 'instance' is a static variable which refers to an instance of SingleObject. But at what point is it actually instantiated and loaded into memory? (If that makes any sense)
It's instantiated the time the class is loaded (that's the time static members are initialized), which is the first time any reference to this class is made. If getInstance is the only member exported by this class (i.e. the only method or member accessible from outside this class), the instance is created the first time getInstance() is called.
It depends. A typical implementation of the Singleton pattern looks like:
class SingleObject {
private static SingleObject instance;
private SingleObject(){
}
public SingleObject getInstance() {
if(instance == null) {
instance = new SingleObject();
}
return instance;
}
}
in which case it's instantiated on the first call to getInstance. But there's no universal rule as to when it needs to be done. A Singleton could also be implemented as:
class SingleObject {
private static SingleObject instance = new SingleObject();
private SingleObject(){
}
public SingleObject getInstance() {
return instance;
}
}
in which case it would be instantiated when the class loads. Wikipedia has a few examples of different implementations.

Singleton object- In static block or in getInstance(); which should be used

Below are two ways to implement a singleton. What are the advantages and disadvantages of each?
Static initialization:
class Singleton {
private Singleton instance;
static {
instance = new Singleton();
}
public Singleton getInstance() {
return instance;
}
}
Lazy initialization is:
class Singleton {
private Singleton instance;
public Singleton getInstance(){
if (instance == null) instance = new Singleton();
return instance;
}
}
Synchronized Accessor
public class Singleton {
private static Singleton instance;
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
lazy load
low perfomance
Double Checked Locking & volatile
public class Singleton {
private static volatile Singleton instance;
public static Singleton getInstance() {
Singleton localInstance = instance;
if (localInstance == null) {
synchronized (Singleton.class) {
localInstance = instance;
if (localInstance == null) {
instance = localInstance = new Singleton();
}
}
}
return localInstance;
}
}
lazy load
high perfomance
JDK should be 1,5 ++
On Demand Holder idiom
public class Singleton {
public static class SingletonHolder {
public static final Singleton HOLDER_INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.HOLDER_INSTANCE;
}
}
lazy load
high performance
cant be used for non static class fields
First one is eager initialisation.
eager initialization creates the instance even before it’s being used and that is not the best practice to use.
Second one is Lazy Initialization.
Lazy implementation works fine incase of single threaded environment but when it comes to multithreaded systems, it can cause issues if multiple threads are inside the if loop at the same time. It will destroy the singleton pattern and both threads will get the different instances of singleton class.
Please visit: http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-with-examples#static-block-initialization for more information
NOTE: static blocks can access only static variables defined outside static block directly. The object you want to restrict to only one instance creation should be static. Your first methods fails during compilation, second method requires you to create the object first Follow this approach:
class Singleton
{
private static Singleton instance;
private Singleton()
{
}
public static Singleton getInstance()
{
if(instance == null)
instance = new Singleton();
return instance;
}
}
Ensure no creation of the object elsewhere, so change the constructor to private
make your class like this
public class Singleton {
private Singleton() {
}
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
and call it like..
Singleton instance = Singleton.getInstance();
Static initializers cannot throw exceptions and absorb RuntimeExceptions into ClassDefNotFoundException, which does not halt execution. So you could see lots of
ClassDefNotFoundException's in your logs and you might not even realize something is wrong until much later because execution continues.
The 2nd method allows RuntimeExceptions to stop execution.
More details here:
https://twasink.net/2006/07/07/how-not-to-handle-exceptions-from-static-code-block-in-java/
Use static static block if you need some things to be initliazedz when the app starts. In it's own. Like you may want to load some properties from some file and do something useful....etc
static {
instance = new Singleton();
loadStuff();
}
Use lazy initialization
class Singleton {
private Singleton instance;
public Singleton getInstance(){
if (instance == null) instance = new Singleton();
loadStuff()
return instance;
}
}
and loadStuff will only be triggered when the Singleton.getInstance() is first called.

Singleton in singleton

I have a singleton in singleton data structure. Currently my implementation is like below:
public class Singleton {
private Object embInstance;
private Singleton() {
embInstance = new Object();
}
private static class SingletonHolder {
public static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
public Object getEmbInstance() {
return embInstance;
}
public Object resetEmbInstance() {
embInstance = null;
}
}
My question are:
Does 'private Singleton()' have to be empty or is it OK to add some code in it?
Is this implementation thread-safe with respect to embInstance?
This implementation is not lazy-loading for embInstance. How to implement a thread-safe lazy-loading for embInstance?
Thanks!
it's ok to add some code to your private, no-args constructor.
I believe the SingletonHolder class will only be initialized once, therefore instance will be guaranteed to be assigned exactly once. However, within the Singleton class you have setters and getters that are not synchronized, so you may have some threading issues there wrt embInstance.
thread-safe lazy-loading: same as lazy-loading, but do it inside a synchronized block:
public static Object getInstance() {
if(embInstance == null) {
synchronized(Singleton.class) {
if(embInstance == null) {
embInstance = new Singleton();
}
}
}
return embInstance;
}
Note that this code is both efficient (no synchronization required once your data is initialized) and thread-safe (initialization occurs inside a synchronized block).
Hope that helps.
The synchronized keyword keeps the methods thread-safe. The getEmbInstance() is the standard way to do lazy instantiation.
public class Singleton {
private Object embInstance;
private Singleton() {
}
private static class SingletonHolder {
public static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
public synchronized Object getEmbInstance() {
if (embInstance == null)
embInstance = new Object();
return embInstance;
}
public synchronized Object resetEmbInstance() {
embInstance = null;
}
}
Not sure, what you mean. It is certainly syntactically acceptable to have code in the Singleton constructor
This is not inherently thread safe. If embInstance is accessed by multiple threads even if it is via getEmbInstance, it will suffer from race conditions. You must use synchronized to access it if you wish for threadsafety.
To implement a thread-safe lazy load, you must have a lock that prevents changes to Singleton. You can just use the instance of Singleton to lock it as such:
synchronized(this)
Also, you don't need SingletonHolder you can just have a public static Singleton instance in the Singleton class itself.
....eh ...isn't that overcomplexifying things? Why have a singleton in a singleton? Why so many classes?
Moreover, you have a method to 'reset' your singleton to null, but none to actually instantiate a new one.
Why not simply:
public class Singleton {
private static Singleton instance;
private Singleton() { }
public static synchronized Singleton getInstance() {
if (instance == null)
instance = new Singleton(); // The "lazy loading" :p
return instance;
}
}
public class A {
A a;
private A() {}
synchronized public static A getOb() {
if (a == null) {
a = new A();
}
return a;
}
}
You should use synchronized for thread-safety in Singleton.

Categories

Resources