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

6

7

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;
    }
}
Gothicize answered 19/3, 2014 at 5:58 Comment(1)
NOTE: static blocks can access only static variables defined outside static block directlyCytogenesis
R
10
  1. 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
  2. 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 ++
  3. 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
Reinhardt answered 19/3, 2014 at 6:12 Comment(0)
G
6

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

Griseous answered 19/3, 2014 at 6:17 Comment(1)
Wonderful example for Singleton patterns. Threadsafe seems the best choice. Bummer, reflection can just destroyCytogenesis
S
1

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();
Stockholder answered 19/3, 2014 at 6:2 Comment(4)
So far, I am using the second approach But In some code I saw that approach too. So, I am not able to decide when that first one is benefecial.Gothicize
@user2155922 First one is same as i am posted with some modifications..but there is a error in your code instance is in static block so it must be static fieldStockholder
@user2155922 and when it comes to the second approch its not valid until your getInstance method is static..otherwise you need to create object to access the getInstance() method then which is not singleton..Stockholder
This happened during typing question...When I was typing the questions It happened.Gothicize
C
1

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

Cytogenesis answered 19/3, 2014 at 6:14 Comment(0)
B
1

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/

Bellflower answered 27/9, 2018 at 1:9 Comment(2)
This is a great point. Is there no way to intercept.Eulalie
The links you shared are broken, BTW.Eulalie
E
0

Use static block if you need some things to be initliazedz when the app starts. f.ex, one may want to load some properties from some file that do useful stuff....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.

Eulalie answered 7/7, 2022 at 3:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.