Thursday, January 24, 2008

Most Popular Developers Interview Question

This is one of the most popular developers interview question I know,

I had been asked about this question so many times.



The question is about the singleton design pattern, how to ensure a single instance of singleton object.



This answer is wrong:



public MySingleton getInstance() {

if (instance==null) {

instance = new MySingleton();

}

return instance;

}



This is because if two thread would call getInstance the same time then they may both enter the if statement before instance was initialized.



Another answer for this question is to initialize instance in the creation of the class.



private static final MySingleton instance = new MySingleton();



but if the classloader is not lazy then this class would be initialized even if no one use it.



A good solution is to initalize it in a static section of the class



static {

instance = new MySingleton();

}



this code would only be called when someone create an instance of the class and two threads can't enter the same time the static section.



Another bad solution is to write



public synchronize MySingleton getInstance() {
if (instance==null) {
instance = new MySingleton();
}
return instance;
}



This is not good solution since each time someone would get instance it would synchronize the call this would decrease the performance.



So a more sophisticated good solution is:



public synchronize MySingleton getInstance() {

if (instance==null) {

synchronize {

if (instnace == null) {

instance = new MySingleton();

}

}

return instance;

}



in this case two threads can enter the first if statement in the first call but then only one of them would get into the second if since the synchronize keyword, this would create only one instance, and also this would create in lazy when the singleton is first access.



Be prepared to be asked about this question in your next interview.

16 comments:

AC said...

With that first synchronize on the getInstance() method, there will be only one thread at the if(). Is that first synchronize a typo?

Anonymous said...

Reconsider your final solution. Here is a link that discusses some alternatives.
http://crazybob.org/2007/01/lazy-loading-singletons.html

Mikkel said...

I disagree.

The synchronized getInstance method is a fine solution to begin with. The end solution reeks of premature optimization and sacrifices readability.

Optimization issues should be worked out while load testing.

Alex Miller said...

You might enjoy my post on double-checked locking.

Grzegorz said...

The last sample holds serious Java concurrency error, eg. double-checked locking.
A Good sample of non trivial singleton

public class Singleton {
private Singleton() {
}

public static Singleton getInstance() {
return Singleton.Holder.instance;
}

private static class Singleton.Holder {
static final Singleton instance = new Singleton();
}
}

john said...

"Singleton.Holder" hmmm dot in class name...intresting...

Grzegorz said...

OK. Sorry for typo. It should be

public class Singleton {
private Singleton() {
}

public static Singleton getInstance() {
return Holder.instance;
}

private static class Holder {
static final Singleton instance = new Singleton();
}
}

Danail Nachev said...

Interesting... I didn't know that there is a difference between static initializer and initialized static variable. According to the JVM specification, there is no difference:

Quote from JVM specification:
...
2.9.2 Initialization of Fields
If a field declaration contains a variable initializer, then it has the semantics of an assignment to the declared variable, and:

* If the declaration is for a class variable (that is, a static field), then the variable initializer is evaluated and the assignment performed exactly once, when the class is initialized (§2.17.4).
...
2.11 Static Initializers
Any static initializers declared in a class are executed when the class is initialized (§2.17.4) and, together with any field initializers (§2.9.2) for class variables, may be used to initialize the class variables of the class (§2.17.4).

The static initializers and class variable initializers are executed in textual order.

End of quote

The best approach is either using static initializer or inner class with static initializer if you think that synchronized getInstance() method will hurt the performance.

Anonymous said...

You probably failed your own interview question. ha...ha...

Anonymous said...

As others have pointed out, this is double locking, and it does not work.

What they were kind enough not to point out is that it was widely debunked 7 years ago.

Furthermore this is a J2EE blog, and in J2EE, synchronized code is frowned upon (certainly in EJB). In J2EE classloaders are many and complex, and there may be muliple copies of your class in the different loader.

Finally you should really consider whether you need a singleton at all. It is only needed where access to a single real resource must be controlled. There is an awful lot of code floating around in the version control systems of the world where singletons are used for utility classes and it reeks of "I've read the Gang of Four book, and now I am going to use it" cluelessness.

willCode4Beer said...

In your lazy init examples, you forgot to declare the instance variable as volatile.

This is a big deal on multi-cpu/multi-core systems. Where synchronized may not be enough (especially when data is in the cache of the cpu).

Mike Kaufman said...

What do you do when a big-company technical lead that is interviewing you is sure enough of a "clever" solution to blog about it, but has it wrong?

If I'd somehow got the desired answer out of them, I'd have explained the problems with double-checked locking etc. But I doubt I'd have thought about that unless they volunteered it. So I guess I'd have done the static initialization and been judged as not knowing the "cleverer" double-checked solution.

Not having a go at anyone - we all have to face this: when interviewing someone, how do you know that your own "model" answers are actually correct? And when being interviewed, how can you tell when facing this situation?

Anonymous said...

Asking about Singleton is boring... There are more important and harder problems than that.

Klaus
www.klaus-meffert.com

Anonymous said...

Who uses Singletons? I thought that GoF pattern had been voted off the island.

Google's written a singleton detector to help you find and eradicate them:

http://code.google.com/p/google-singleton-detector/

Spring doesn't have any singletons.

I thought it was completely discredited.

All the other stuff about double checked locking also applies, of course.

The interviewer risks losing the candidate after asking this question.

Scott Vachalek said...

The above comment on the static unit spec is correct. If you examine the two classes with javap -p -c you will see they are identical.

Robert said...

For bonus points, please point out the flaw in the implementation which makes it possible to get two instances of the singleton in a single JVM (yes, it's possible - almost trivially easy, in fact)

Links

 
RSS Feeds Submission Directory