3

I am trying to figure out the answer to the following MC question. I have tried looking for an answer on google but people seem to have different answers for this problem. Can someone please explain their answer.

public class Gingleton {
    private static Gingleton INSTANCE = null;

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

    private Gingleton() {
    }
}
  • More than one instance of Gingleton can be created (My choice)

  • A Gingleton will never be created

  • The constructor is private and can't be called

  • value can be garbage collected, and the call to getInstance may return garbage data

Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162
user3353723
  • 221
  • 1
  • 7
  • 15

2 Answers2

5

New instance creation in getInstance() is not synchronized in any way, so it IS possible that more than one instance will be created in mulithreaded environment. To ensure only one instance you should do:

public class Gingleton {

    // volatile
    private static volatile Gingleton INSTANCE = null;

    public static Gingleton getInstance()
    {
        if ( INSTANCE == null )
        {
            synchronized (Gingleton.class) {  // Synchronized
                if ( INSTANCE == null )
                {
                    INSTANCE = new Gingleton();
                }
            }
        }
        return INSTANCE;
    }

    private Gingleton() {
    }
}
Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162
  • nice answer, can you add little explanation about why `volatile` needed, and why two null check. – Abhishek Nayak Mar 09 '14 at 13:12
  • 2
    @Rembo [Volatile is the only reason the above example works. (Read this whole thing, there is not a little explanation.)](http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html) – Radiodef Mar 09 '14 at 13:14
3

More than one instance (per JVM) could (probably accidently) be created, if some race condition occur.

This code actually reflect a "lazy singleton pattern", i.e. the purpose would be to have only one instance per JVM, created at the moment when it is first accessed.

=> at first glance we could only have once instance of it. However, since the code is not synchronized, it could happen that this part of the code is executed several times in parallel in a multi-thread environment.

if ( INSTANCE == null )
    {
        INSTANCE = new Gingleton();
    }

See also comments here

Singleton pattern with combination of lazy loading and thread safety

singleton pattern in java. lazy initialization

So I would say this is bad question and you could bash the MC author in the head, because:

  • More than one instance of Gingleton can be created (My choice)

=> True, given discussion above, but that is probably not be what the author of the question has in mind

  • A Gingleton will never be created

=> errr, well, getInstance() is never called in this snippet => nope, no instance is created. But probably the author has in mind that we could call this method, in which case the answer is yes

  • The constructor is private and can't be called

A private constructor can be called... just not from outside the class. Again, the author is not formulating it but we could assume that he or she only thinks of the case "from outside"

  • value can be garbage collected, and the call to getInstance may return garbage data

Ah, this statement at least is clear. No, the static field will not be garbage collected, you can rely on its value.

Community
  • 1
  • 1
Svend
  • 6,352
  • 1
  • 25
  • 38
  • I gave you my +1 for pointing out the absurdity of the options. It's pretty difficult to tell what the intended 'correct' answer is. – Radiodef Mar 09 '14 at 13:03
  • I think pointing out that `getInstance()` is never called is just being pedantic – DeadChex Mar 09 '14 at 13:11
  • @Radiodef Thanks! Reading the examiner's mind is a subtle art indeed :). I personally would have guessed 3, the question and multi answer feel like the kind of things we get to when we start learning java, so probably multi-threading is out of scope in the context of this class and the point is to underline the usage of method access modifiers. – Svend Mar 09 '14 at 13:16
  • @DeadChex, ok ok, I guess you're right. Still I feel it frustrating to have to guess the level of rigour that is expected when being examined. – Svend Mar 09 '14 at 13:17
  • @Svend I'm still going back and forth on what I think the intended answer is. I'm beginning to also land on #3 because I think the question is supposed to test on access modifiers. It's the only way to look at it and have it make sense as a whole. – Radiodef Mar 09 '14 at 13:26