Singleton pattern interview

2020-05-24 08:57发布

问题:

I am recently asked about java related question in an interview with following code, since I am very new to java and barely code in Java so I really have no idea what the following code does.

The question was Select the option that describes the worst thing with the following code:

public class Bolton {
    private static Bolton INST = null;

    public static Bolton getInstance()
    {
        if ( INST == null )
        {
            INST = new Bolton();
        }
        return INST;
    }

    private Bolton() {
    }
}

Here are the options for this question

  1. More than one instance of Bolton can be created
  2. A Bolton will never be created
  3. The constructor is private and can't be called
  4. Value can be garbage collected, and the call to getInstance may return garbage data

Which of the above options is correct? And Why?

回答1:

This is a Singleton Pattern

The idea of a Singleton Pattern is to only have one available instance of a class. Therefore the constructor is set to private and the class maintains, in this case, a getInstance() method that either calls an existing instance variable, INST in this class, or creates a new one for the executing program. The answer is probably 1, because it's not thread safe. It may be confused for 3, which I had put down earlier, but that is by design, technically, so not actually a flaw.

Here's an example of Lazy Initialization, thread-safe singleton pattern from Wikipedia:

public class SingletonDemo {

    private static volatile SingletonDemo instance = null;

    private SingletonDemo() {  } 

    public static SingletonDemo getInstance() {
        if (instance == null) {
            synchronized (SingletonDemo.class){
                if (instance == null) {
                    instance = new SingletonDemo();
                }
            }
        }
        return instance;
    }

}

Setting the instance variable to volatile tells Java to read it from memory and to not set it in cache.

Synchronized statements or methods help with concurrency.

Read more about double checked locking which is what happens for a "lazy initialization" singleton



回答2:

More than one instance of Bolton can be created

This option is correct due to lack of synchronization in the above code.

Suppose two threads concurrently check for null and both will find that the value is null and both will call the constructor (which refutes singleton).

Also there is other catch in this, even if two threads dont check for null together but suppose one thread calls the constructor; but the constructor wont return till the object is constructed (assuming that the object is costly to create and requires time), so till the constructor returns some other thread might check for the null condition and still find the object as null as the object is not yet constructed.

This scenario in which some pre condition is called check-then-act which is culprit for Race.

For singleton there are two standards that are being used:

  • Double Checked locking
  • Enum based singleton pattern

UPDATE: Here is another great article which discusses the double checked locking



回答3:

Interviewer basically wants to check your knoweldge of Singleton pattern . Can the pattern be broken?. Ans is Yes. Check this or google - when singleton is not a singleton.

Best course is to use Enum based Singleton as suggested by Joshua Bloch



回答4:

The getInstance() method should be synchronized, otherwise many instances could be created if multiple threads calls getInstance() at the same time. So I would select option 1.



回答5:

We use Singleton Pattern when we want to have only one object of this class and it will be used every where. So to restrict the class to create many objects, we should use private for constructor of this class. And create one public function to return the object of this class.

public class MethodWin {
    private int isLoggedOn=0;
    private static MethodWin objectMethodWin = new MethodWin();
    private MethodWin() { }
    public static MethodWin getInstance() {
        return objectMethodWin;
    }
    public void setIsLoggedOn(int value) {
       this.isLoggedOn=value;
    }
    public int getIsLoggedOn() {
       return this.isLoggedOn;
    }
}

So when we need to create this obect, we should:

MethodWin meth = MethodWin.getInstance();


回答6:

Original Answer is that only one instance of Bolton is created.



回答7:

Through reflection we can create many objects even if the constructor is private.
In multi-threaded environment there are chances to create more than one instance.
Through serialization there are chances to create more than one object.



回答8:

simple answer is 2) A Bolton will never be created because when you create instance the constructor will call inside constructor initialization when call getInstance method then answer will be single instance will be created.