209
190
|
What is an efficient way to implement a singleton pattern in Java?
| ||||||||||||||||||||
|
271
|
Use an enum:
Joshua Bloch explained this approach in his Effective Java Reloaded talk at Google I/O 2008: link to video. Also see slides 30-32 of his presentation (effective_java_reloaded.pdf):
Edit: An online portion of "Effective Java" says:
| ||||||||||||||||||||
|
98
|
Depending on the usage, there are several "correct" answers.
Since java5 the best way to do it is to use an enum:
Pre java5, the most simple case is:
Let's go over the code. First, you want the class to be final. In this case, I've used the
final keyword to let the users know it is final. Then you need to make the constructor private to prevent users to create their own Foo. Throwing an exception from the constructor prevents users to use reflection to create a second Foo. Then you create a private static final Foo field to hold the only instance, and apublic static Foo getInstance() method to return it. The Java specification makes sure that the constructor is only called when the class is first used.
When you have a very large object or heavy construction code AND also have other accessible static methods or fields that might be used before an instance is needed, then and only then you need to use lazy initialization.
You can use a
private static class to load the instance. The code would then look like:
Since the line
private static final Foo INSTANCE = new Foo(); is only executed when the class FooLoader is actually used, this takes care of the lazy instantiation, and is it guaranteed to be thread safe.
When you also want to be able to serialize your object you need to make sure that deserialization won't create a copy.
The method
readResolve() will make sure the only instance will be returned, even when the object was serialized in a previous run of your program. | ||||||||||||||||||||
|
66
|
The solution posted by Stu Thompson is valid in Java5.0 and later. But I would prefer not to use it because I think it is error prone.
It's easy to forget the volatile statement and difficult to understand why it is necessary. Without the volatile this code would not be thread safe anymore due to the double-checked locking antipattern. See more about this in paragraph 16.2.4 of Java Concurrency in Practice. In short: This pattern (prior to Java5.0 or without the volatile statement) could return a reference to the Bar object that is (still) in an incorrect state.
This pattern was invented for performance optimization. But this is really not a real concern anymore. The following lazy initialization code is fast and -more importantly- easier to read.
| ||||||||||||||||
|
50
|
Thread safe in Java 5+:
EDIT: Pay attention to the volatile modifier here. :) It is important because without it, other threads are not guaranteed by the JMM (Java Memory Model) to see changes to its value. The synchronization does not take care of that--it only serializes access to that block of code.
EDIT 2: @Bno 's answer details the approach recommended by Bill Pugh (FindBugs) and is arguable better. Go read and vote up his answer too.
| ||||||||||||
|
33
|
Forget lazy initialization, it's too problematic. This is the simplest solution:
| ||||||||||||||||||||
|
28
|
Make sure that you really need it. Do a google for "singleton anti-pattern" to see some arguments against it. There's nothing inheritantly wrong with it I suppose but it's just a mechanism for exposing some global resource/data so make sure that this is the best way. In particular I've found dependency injection more useful particularly if you are also using unit tests because DI allows you to use mocked resources for testing purposes.
| ||||
|
16
|
Don't forget the Singleton is only a Singleton for the Classloader that loaded it. If you are using multiple loaders (Containers) each COULD have its own version of the Singleton.
| ||||
|
12
|
I'm mystified by some of the answers that suggest DI as an alternative to using singletons; these are unrelated concepts. You can use DI to inject either singleton or non-singleton (e.g. per-thread) instances. At least this is true if you use Spring 2.x, I can't speak for other DI frameworks.
So my answer to the OP would be (in all but the most trivial sample code) to:
This approach gives you a nice decoupled (and therefore flexible and testable) architecture where whether to use a singleton is an easily reversible implementation detail (provided any singletons you use are threadsafe, of course).
| ||||||||||||||||
|
11
|
Really consider why you need a singleton before writing it. There is a quasi-religious debate about using them which you can quite easily stumble over if you google singletons in Java.
Personally I try to avoid singletons as often as possible for many reasons, again most of which can be found by googling singletons. I feel that quite often singletons are abused because they're easy to understand by everybody, they're used as a mechanism for getting "global" data into an OO design and they are used because it is easy to circumvent object lifecycle management (or really thinking about how you can do A from inside B). Look at things like Inversion of Control (IoC) or Dependency Injection (DI) for a nice middleground.
If you really need one then wikipedia has a good example of a proper implementation of a singleton.
|