1

I have read his basic Java implementation of Singleton, because I will have a presentation in my class about design patterns:

public final class ClassSingleton {

    private static ClassSingleton INSTANCE;
    private String info = "Initial info class";

    private ClassSingleton() {        
    }

    public static ClassSingleton getInstance() {
        if(INSTANCE == null) {
            INSTANCE = new ClassSingleton();
        }

        return INSTANCE;
    }

    // getters and setters
}

Having used it certain times, I'm quite familiar with it. However, when I got deeper into the topic, I found out that this version is not thread safe at all.

What does this mean exactly? If multiple threads access it and create a new instance, will more different instances be created? Or where does the "safety" cease to exist?

Thanks for your answer in advance.

lyancsie
  • 658
  • 7
  • 18
  • 2
    More instances can *possibly* exist if you're unlucky enough that it is accessed at the same time so both threads get past the `if(INSTANCE == null)` at the same time. – EpicPandaForce Jan 04 '19 at 09:59

2 Answers2

6

More instances can possibly exist if you're unlucky enough that it is accessed at the same time so both threads get past the if(INSTANCE == null) at the same time.

That is why you typically instead do

public final class ClassSingleton {

    private static volatile ClassSingleton INSTANCE;
    private String info = "Initial info class";

    private ClassSingleton() {        
    }

    private static final Object lock = new Object();

    public static ClassSingleton getInstance() {
        if(INSTANCE == null) {
            synchronized(lock) {
                if(INSTANCE == null) {
                    INSTANCE = new ClassSingleton();
                }
            }
        }

        return INSTANCE;
    }

    // getters and setters
}

As it forces a thread to wait if there is already another thread inside the monitor of lock, initializing the singleton.

(EDIT: also, i'm glad the duplicate question is "why to use volatile", I figured it should be necessary so I added it :p otherwise the other thread wouldn't see immediate changes to this shared variable. Another option instead of volatile would be to use AtomicReference<T>.)

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
1

Suppose multiple threads try to get an instance of your singleton class, they call the below method simultaneously:

public static ClassSingleton getInstance() {
        if(INSTANCE == null) {
            INSTANCE = new ClassSingleton();
        }
    return INSTANCE;
}

INSTANCE == null will be true for both of the threads and they will both end up creating a new instance.

Aditya Narayan Dixit
  • 2,105
  • 11
  • 23