I have read about many possible ways to create a singleton for the multithreaded environment in Java, like Enums, Double-check locking, etc.
I found a simple way that is also working fine and I unable to find its drawbacks or failure cases. May anyone explain when it may fail or why we should not choose this approach.
public final class MySingleton {
public final static MySingleton INSTANCE = new MySingleton();
private MySingleton(){}
}
I am testing it with the below code and working fine:
public class MyThread {
public static void main(String[] args) {
for (int i = 0; i < 10000; i++) {
Thread thread = new Thread(() -> {
MySingleton singleton = MySingleton.INSTANCE;
System.out.println(singleton.hashCode() + " " + Thread.currentThread().getName());
});
thread.start();
}
}
}
Every comment is appreciated.
Your singleton is instantiated when the class is loaded, therefore when the main method is started, it is already instantiated and from a multithreading perspective is safe.
But there are some arguments why this might not be the best approach:
When instantiating your singleton throws an exception, you get a nasty classloading exception which is hard to analyze, especially when you don't have a debugger to attach.
When instantiating takes some time, so you might don't want to do this when the class is loaded in order to minimize the startup time of your application
And additionally using singletons is not a good design as you hardcode the dependency between the client (that uses this class) and the implementation of this class. So it is hard to replace your implementation with a mock for testing.
Yes, this is a fine implementation of a singleton.
The test shows... something; but it doesn't really explain whether it's working or not. What you are trying to show (that only one instance is created) is essentially impossible to show with a test, because it's something that's guaranteed by the language spec.
See JLS 12, in particular JLS 12.4, which describes how classes are initialized.
For each class or interface C, there is a unique initialization lock LC. The mapping from C to LC is left to the discretion of the Java Virtual Machine implementation. The procedure for initializing C is then as follows:
Synchronize on the initialization lock, LC, for C. This involves waiting until the current thread can acquire LC.
If the Class object for C indicates that initialization is in progress for C by some other thread, then release LC and block the current thread until informed that the in-progress initialization has completed, at which time repeat this step.
If the Class object for C indicates that initialization is in progress for C by the current thread, then this must be a recursive request for initialization. Release LC and complete normally.
If the Class object for C indicates that C has already been initialized, then no further action is required. Release LC and complete normally.
...
So, classes are guaranteed to only be initialized once (if at all), because the initialization is done whilst holding a class-specific lock; the happens-before guarantees of acquiring and releasing that lock mean that the values of final fields are visible; so the INSTANCE field is guaranteed to be initialized once, and thus there is only one instance of MySingleton possible.
Note that your implementation is effectively the same as an enum:
public enum MySingleton {
INSTANCE
}
Enums are really just syntactic sugar for classes. If you decompiled an enum class, it would look something like:
public class MySingleton {
public static final MySingleton INSTANCE = new MySingleton(0);
private MySingleton(int ordinal) { ... }
}
It is perfectly fine and simple. Although you may check the trade offs listed below:
May lead to resource wastage. Because instance of class is created always, whether it is required or not.
CPU time is also wasted for creating the instance if it is not required.
Exception handling is not possible.
Also you have to be sure that MySingleton class is thread-safe
See
Java Singleton Design Pattern Practices with Examples
Ah, I ran into some problems using exactly this approach a few months ago. Most people here will tell you this is fine, and they are mostly right, as long as you know the constructor won't throw an exception. What I'm about to describe is a common but unpredictable artifact of JVM caching conventions.
I had a singleton that was set up exactly the one you show in your question. Every time I attempted to run the program I got a NoClassDefFoundError. I had no idea what was going wrong until I found this post on Reddit, aptly titled Using static initialization for singletons is bad!
Just FYI, if you initialize a singleton with static initialization, e.g., private static final MyObject instance = new MyObject(); and there's business logic in your constructor, you can easily run into weird meta-errors, like NoClassDefFoundError. Even worse, it's unpredictable. Certain conditions, such as the OS, can change whether an error occurs or not. Static initialization also includes using a static block, "static{...}" , and using the enum singleton pattern.
The post also links to some Android docs about the cause of the problem.
The solution, which worked very well for me, is called double checked locking.
public class Example {
private static volatile Example SINGLETON = null;
private static final Object LOCK = new Object();
private Example() {
// ...do stuff...
}
public static Example getInstance() {
if (SINGLETON == null) {
synchronized (LOCK) {
if (SINGLETON == null) {
SINGLETON = new Example();
}
}
}
return SINGLETON;
}
}
For the most part, you can probably do it the simple way without problems. But, if your constructor contains enough business logic that you start getting NoClassDefFoundError, this slightly more complicated approach should fix it.
Related
According to this post, the thread-safe singleton class should look as below. But I'm wondering whether there's a need to add volatile keyword to static CrunchifySingleton instance variable. Since if the instance is created and stored in CPU cache, at which time it is not written back to main memory, meanwhile, another thread invoke on getInstance() method. Will it incur an inconsistency problem?
public class CrunchifySingleton {
private static CrunchifySingleton instance = null;
protected CrunchifySingleton() {
}
// Lazy Initialization
public static CrunchifySingleton getInstance() {
if (instance == null) {
synchronized (CrunchifySingleton.class) {
if (instance == null) {
instance = new CrunchifySingleton();
}
}
}
return instance;
}
}
I echo #duffymo's comment above: lazy singletons are nowhere near as useful as they initially appear.
However, if you absolutely must use a lazily-instantiated singleton, the lazy holder idiom is much a easier way to achieve thread safety:
public final class CrunchifySingleton {
private static class Holder {
private static final CrunchifySingleton INSTANCE = new CrunchifySingleton();
}
private CrunchifySingleton() {}
static CrunchifySingleton getInstance() { return Holder.INSTANCE; }
}
Also, note that to be truly singleton, the class needs to prohibit both instantiation and subclassing - the constructor needs to be private, and the class needs to be final, respectively.
Yep, if your Singleton instance is not volatile or even if it is volatile but you are using sufficiently old JVM, there's no ordering guarantees for the operations in which the line
instance = new CrunchifySingleton();
decomposes with regard to the volatile store.
The compiler can then reorder these operations so that your instance is not null (because memory has been allocated), but is still uninitialized (because its constructor still hasn't been executed).
If you want to read more about the hidden problems around Double-Checked Locking, specifically in Java, see The "Double-Checked Locking is Broken" Declaration.
The lazy holder idiom is a nice pattern that generalizes well for general static field lazy loading, but if you need a safe and simple Singleton pattern, I'd recommend what Josh Bloch (from Effective Java fame) recommends - the Java Enum Singleton:
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
The code how you quoted it is broken in Java. Yes, you need volatile and at least Java 5 to make the double-checked idiom thread safe. And you should also add a local variable in your lazy initialization to improve performance. Read more about it here: https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
Yes, making volatile will gaurantee that every time any thread is trying to access your critical section of code, the thread reads the data from memory itself and not from hread cache.
You need volatile in this case but a better option is to use either an enum if it is stateless
enum Singleton {
INSTANCE;
}
however stateful singletons should be avoid every possible. I suggest you try creating an instance which you pass via dependency injection.
I sometimes see that people create self instance for example:
public class Example extends Service
{
private static Example mInstance = null;
public void onStart( Intent aIntent, int aStartId )
{
mInstance = this;
.
.
.
}
}
What is the purpose of this?
This is called the Singleton design pattern. Singletons are used when there is going to be a single instance of an object performing operations on non-static data.
See here.
In addition to what other answers put about Singleton pattern, self instances may be used as constants. That's the case of the Color class, that defines an instance for each of the common colours.
http://docs.oracle.com/javase/7/docs/api/java/awt/Color.html
An Android Service (sub)class cannot be a singleton since the framework requires access to a default constructor for the class. The only reason I can think of for keeping a static reference to the (last) instance for which onStart was called is to simplify some internal code that may happen to reside in static methods.
Considering that onStart was deprecated a long time ago (as of API level 5), this is most likely an example of bad coding style from early days of Android.
So that other classes can get an instance and call instance methods on the object. Its frequently used with the Singleton pattern. And for Services and Activities in Android it's a very bad idea- it keeps a reference to the Activity/Service around after it ends, which will cause a memory leak.
In a thread-unsafe singleton pattern implementation, you would have a private constructor, and a public static getInstance method initializing that instance if necessary and returning it.
Here's an example. Note that it is advised to leverage the commodity of a single-element enum instead of the code below, to achieve a "true" singleton.
public class MyThreadUnsafeSingleton {
private static MyThreadUnsafeSingleton instance;
private MyThreadUnsafeSingleton() {
//TODO some ctor logic
}
public static MyThreadUnsafeSingleton getInstance() {
if (instance == null) {
instance = new MyThreadUnsafeSingleton();
}
return instance;
}
}
Final note, there is a variation of the above pattern that is thread-safe across a single classloader through the usage of a nested "holder" class, but that's quite out of scope.
If it has a private default constructor, it's probably a singleton.
If it doesn't, it's something weird.
This sort of layout forces all object instances of this class to share data, regardless of when they are instantiated. The object instance on which OnStart is called will become the underlying data source for any references to this class, regardless of when they were declared or instantiated (before or after OnStart), and regardless of what thread they were created on.
Of course it is always possible there are members of the class that don't bother with mInstance.Member and use this.Member instead. That sort of mixing and matching would probably end up being disastrous.
It's hard to imagine the specific use for this but my guess is that the class is an abstraction of some stateful resource that is global with respect to the process, e.g. a form/window or a web service client that caches its credentials. Could be anything though.
If this code was written around 2003-2005 (early c# days) I'd guess that it is a sloppy implementation of a Singleton-- it was sort of in vogue back then as design patterns were becoming a thing and Singleton was the example in all the textbooks. Turns out it's a horrible pattern for dependency injection and mocking, so these days this pattern doesn't get used as much.
This paradigm is often used for objects that are heavy or slow to construct and only one is needed.
public class Server {
private static Server server = null;
// Stop them making their own.
private Server () {
// Heavyweight stuff.
}
public static Server getServer () {
if ( server == null ) {
// Heavy constructor.
server = new Server();
}
return server;
}
}
In a multi-thread environment it is usually combined with the singleton design pattern.
Below show is the creation on the singleton object.
public class Map_en_US extends mapTree {
private static Map_en_US m_instance;
private Map_en_US() {}
static{
m_instance = new Map_en_US();
m_instance.init();
}
public static Map_en_US getInstance(){
return m_instance;
}
#Override
protected void init() {
//some code;
}
}
My question is what is the reason for using a static block for instantiating. i am familiar with below form of instantiation of the singleton.
public static Map_en_US getInstance(){
if(m_instance==null)
m_instance = new Map_en_US();
}
The reason is thread safety.
The form you said you are familiar with has the potential of initializing the singleton a large number of times. Moreover, even after it has been initialized multiple times, future calls to getInstance() by different threads might return different instances! Also, one thread might see a partially-initialized singleton instance! (let's say the constructor connects to a DB and authenticates; one thread might be able to get a reference to the singleton before the authentication happens, even if it is done in the constructor!)
There are some difficulties when dealing with threads:
Concurrency: they have to potential to execute concurrently;
Visibility: modifications to the memory made by one thread might not be visible to other threads;
Reordering: the order in which the code is executed cannot be predicted, which can lead to very strange results.
You should study about these difficulties to understand precisely why those odd behaviors are perfectly legal in the JVM, why they are actually good, and how to protect from them.
The static block is guaranteed, by the JVM, to be executed only once (unless you load and initialize the class using different ClassLoaders, but the details are beyond the scope of this question, I'd say), and by one thread only, and the results of it are guaranteed to be visible to every other thread.
That's why you should initialize the singleton on the static block.
My preferred pattern: thread-safe and lazy
The pattern above will instantiate the singleton on the first time the execution sees a reference to the class Map_en_US (actually, only a reference to the class itself will load it, but might not yet initialize it; for more details, check the reference). Maybe you don't want that. Maybe you want the singleton to be initialized only on the first call to Map_en_US.getInstance() (just as the pattern you said you are familiar with supposedly does).
If that's what you want, you can use the following pattern:
public class Singleton {
private Singleton() { ... }
private static class SingletonHolder {
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
In the code above, the singleton will only be instantiated when the class SingletonHolder is initialized. This will happen only once (unless, as I said before, you are using multiple ClassLoaders), the code will be executed by only one thread, the results will have no visibility problems, and the initialization will occur only on the first reference to SingletonHolder, which happens inside the getInstance() method. This is the pattern I use most often when I need a singleton.
Another patterns...
1. synchronized getInstace()
As discussed in the comments to this answer, there's another way to implement the singleton in a thread safe manner, and which is almost the same as the (broken) one you are familiar with:
public class Singleton {
private static Singleton instance;
public static synchronized getInstance() {
if (instance == null)
instance = new Singleton();
}
}
The code above is guaranteed, by the memory model, to be thread safe. The JVM specification states the following (in a more cryptic way): let L be the lock of any object, let T1 and T2 be two threads. The release of L by T1 happens-before the acquisition of L by T2.
This means that every thing that has been done by T1 before releasing the lock will be visible to every other thread after they acquire the same lock.
So, suppose T1 is the first thread that entered the getInstance() method. Until it has finished, no other thread will be able to enter the same method (since it is synchronized). It will see that instance is null, will instantiate a Singleton and store it in the field. It will then release the lock and return the instance.
Then, T2, which was waiting for the lock, will be able to acquire it and enter the method. Since it acquired the same lock that T1 just released, T2 will see that the field instance contains the exact same instance of Singleton created by T1, and will simply return it. What is more, the initialization of the singleton, which has been done by T1, happened before the release of the lock by T1, which happened before the acquisition of the lock by T2, therefore there's no way T2 can see a partially-initialized singleton.
The code above is perfectly correct. The only problem is that the access to the singleton will be serialized. If it happens a lot, it will reduce the scalability of your application. That's why I prefer the SingletonHolder pattern I showed above: access to the singleton will be truly concurrent, without the need for synchronization!
2. Double checked locking (DCL)
Often, people are scared about the cost of lock acquisition. I've read that nowadays it is not that relevant for most applications. The real problem with lock acquisition is that it hurts scalability by serializing access to the synchronized block.
Someone devised an ingenuous way to avoid acquiring a lock, and it has been called double-checked locking. The problem is that most implementations are broken. That is, most implementations are not thread-safe (ie, are as thread-unsafe as the getInstace() method on the original question).
The correct way to implement the DCL is as follows:
public class Singleton {
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
The difference between this correct and an incorrect implementation is the volatile keyword.
To understand why, let T1 and T2 be two threads. Let's first assume that the field is not volatile.
T1 enters the getInstace() method. It's the first one to ever enter it, so the field is null. It then enters the synchronized block, then the second if. It also evaluates to true, so T1 creates a new instance of the singleton and stores it in the field. The lock is then release, and the singleton is returned. For this thread, it is guaranteed that the Singleton is completely initialized.
Now, T2 enters the getInstace() method. It is possible (although not guaranteed) that it will see that instance != null. It will then skip the if block (and so it will never acquire the lock), and will directly return the instance of the Singleton. Due to reordering, it is possible that T2 will not see all the initialization performed by the Singleton in its constructor! Revisiting the db connection singleton example, T2 might see a connected but not yet authenticated singleton!
For more information...
... I'd recommend a brilliant book, Java Concurrency in Practice, and also, the Java Language Specification.
If you initialize in the getInstance() method, you can get a racing conditions, i.e. if 2 threads execute the if(m_instance == null) check simulataneously, both might see the instance be null and thus both might call m_instance = new Map_en_US();
Since the static initializer block is executed only once (by one thread that is executing the class loader), you don't have a problem there.
Here's a good overview.
How about this approach for eradicating the static block:
private static Map_en_US s_instance = new Map_en_US() {{init();}};
It does the same thing, but is way neater.
Explanation of this syntax:
The outer set of braces creates an anonymous class.
The inner set of braces is called an "instance block" - it fires during construction.
This syntax is often incorrectly called the "double brace initializer" syntax, usually by those who don't understand what is going on.
Also, note:
m_ is a naming convention prefix for instance (ie member) fields.
s_ is a naming convention prefix for class (ie static) fields.
So I changed the name of the field to s_....
It depends on how resource-intensive the init method is. If it e.g. does a lot of work, maybe you want that work done at the startup of the application instead of on the first call. Maybe it downloads the map from Internet? I don't know...
The static block is executed when the class is first loaded by the JVM. As Bruno said, that helps with thread safety because there isn't a possibility that two threads will fight over the same getInstance() call for the first time.
With static instantiation there will be only one copy of the instance per class irrespective of how many objects being created.
Second advantage with the way is, The method is thread-safeas you are not doing anything in the method except returning the instance.
the static block instances your class and call the default contructor (if any) only one time and when the application starts and all static elements are loaded by the JVM.
Using the getInstance() method the object for the class is builded and initialized when the method is called and not on the static initialization. And is not really safe if you are running the getInstance() in diferent threads at the same time.
static block is here to allow for init invocation. Other way to code it could be eg like this (which to prefer is a matter of taste)
public class Map_en_US extends mapTree {
private static
/* thread safe without final,
see VM spec 2nd ed 2.17.15 */
Map_en_US m_instance = createAndInit();
private Map_en_US() {}
public static Map_en_US getInstance(){
return m_instance;
}
#Override
protected void init() {
//some code;
}
private static Map_en_US createAndInit() {
final Map_en_US tmp = new Map_en_US();
tmp.init();
return tmp;
}
}
update corrected per VM spec 2.17.5, details in comments
// Best way to implement the singleton class in java
package com.vsspl.test1;
class STest {
private static STest ob= null;
private STest(){
System.out.println("private constructor");
}
public static STest create(){
if(ob==null)
ob = new STest();
return ob;
}
public Object clone(){
STest obb = create();
return obb;
}
}
public class SingletonTest {
public static void main(String[] args) {
STest ob1 = STest.create();
STest ob2 = STest.create();
STest ob3 = STest.create();
System.out.println("obj1 " + ob1.hashCode());
System.out.println("obj2 " + ob2.hashCode());
System.out.println("obj3 " + ob3.hashCode());
STest ob4 = (STest) ob3.clone();
STest ob5 = (STest) ob2.clone();
System.out.println("obj4 " + ob4.hashCode());
System.out.println("obj5 " + ob5.hashCode());
}
}
-------------------------------- OUT PUT -------------------------------------
private constructor
obj1 1169863946
obj2 1169863946
obj3 1169863946
obj4 1169863946
obj5 1169863946
Interesting never seen that before. Seems largely a style preference. I suppose one difference is: the static initialisation takes place at VM startup, rather than on first request for an instance, potentially eliminating an issue with concurrent instantiations? (Which can also be handled with synchronized getInstance() method declaration)
A recent question here had the following code (well, similar to this) to implement a singleton without synchronisation.
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
Now, I think understand what this is doing. Since the instance is static final, it's built long before any threads will call getInstance() so there's no real need for synchronisation.
Synchronisation would be needed only if two threads tried to call getInstance() at the same time (and that method did construction on first call rather than at "static final" time).
My question is therefore basically: why then would you ever prefer lazy construction of the singleton with something like:
public class Singleton {
private Singleton() {}
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
if (instance == null)
instance = new Singleton();
return instance;
}
}
My only thoughts were that using the static final method may introduce sequencing issue as in the C++ static initialisation order fiasco.
First off, does Java actually have this problem? I know order within a class is fully specified but does it somehow guarantee consistent order between classes (such as with a class loader)?
Secondly, if the order is consistent, why would the lazy construction option ever be advantageous?
Now, I think understand what this is doing. Since the instance is static final, it's built long before any threads will call getInstance() so there's no real need for synchronisation.
Not quite. It is built when the SingletonHolder class is initialized which happens the first time getInstance is called. The classloader has a separate locking mechanism, but after a class is loaded, no further locking is needed so this scheme does just enough locking to prevent multiple instantiation.
First off, does Java actually have this problem? I know order within a class is fully specified but does it somehow guarantee consistent order between classes (such as with a class loader)?
Java does have a problem where a class initialization cycle can lead to some class observing another class's static finals before they are initialized (technically before all static initializer blocks have run).
Consider
class A {
static final int X = B.Y;
// Call to Math.min defeats constant inlining
static final int Y = Math.min(42, 43);
}
class B {
static final int X = A.Y;
static final int Y = Math.min(42, 43);
}
public class C {
public static void main(String[] argv) {
System.err.println("A.X=" + A.X + ", A.Y=" + A.Y);
System.err.println("B.X=" + B.X + ", B.Y=" + B.Y);
}
}
Running C prints
A.X=42, A.Y=42
B.X=0, B.Y=42
But in the idiom you posted, there is no cycle between the helper and the singleton so there is no reason to prefer lazy initialization.
Now, I think understand what this is
doing. Since the instance is static
final, it's built long before any
threads will call getInstance() so
there's no real need for
synchronisation.
No. SingletonHolder class will be loaded only when you invoke SingletonHolder.INSTANCE for the very first time. final Object will become visible to other threads only after it is fully constructed. Such lazy initialization is called Initialization on demand holder idiom.
In Effective Java, Joshua Bloch notes that "This idiom … exploits the guarantee that a class will not be initialized until it is used [JLS, 12.4.1]."
The patern that you described works for two reasons
Class is loaded and initialized when first accessed (via SingletonHolder.INSTANCE here)
Class loading and initialization is atomic in Java
So you do perform lazy initialization in a thread safe and efficient way. This pattern is better alternative to double lock (not working) solution to synchronized lazy init.
You initialize eagerly because you don't have to write a synchronized block or method. This is mainly because synchronization is generally considered expensive
Just a little note about the first implementation: the interesting thing here is that class initialization is used to replace classical synchronization.
Class initialization is very well defined in that no code can ever get access to anything of the class unless it is fully initialized (i.e. all static initializer code has run). And since an already loaded class can be accessed with about zero overhead, this restricts the "synchronization" overhead to those cases where there is an actual check to be done (i.e. "is the class loaded/initialized yet?").
One drawback of using the class loading mechanism is that it can be hard to debug when it breaks. If, for some reason, the Singleton constructor throws an exception, then the first caller to getInstance() will get that exception (wrapped in another one).
The second caller however will never see the root cause of the problem (he will simply get a NoClassDefFoundError). So if the first caller somehow ignores the problem, then you'll never be able to find out what exactly went wrong.
If you use simply synchronization, then the second called will just try to instantiate the Singleton again and will probably run into the same problem (or even succeed!).
A class is initialized when it's accessed at runtime. So init order is pretty much the execution order.
"Access" here refers to limited actions specified in the spec. The next section talks about initialization.
What's going on in your first example is equivalently
public static Singleton getSingleton()
{
synchronized( SingletonHolder.class )
{
if( ! inited (SingletonHolder.class) )
init( SingletonHolder.class );
}
return SingletonHolder.INSTANCE;
}
( Once initialized, the sync block becomes useless; JVM will optimize it off. )
Semantically, this is not different from the 2nd impl. This doesn't really outshine "double checked locking", because it is double checked locking.
Since it piggybacks on class init semantics, it only works for static instances. In general, lazy evaluation is not limited to static instances; imagine there's an instance per session.
First off, does Java actually have this problem? I know order within a class is fully specified but does it somehow guarantee consistent order between classes (such as with a class loader)?
It does, but to a lesser degree than in C++:
If there is no dependency cycle, the static initialization occurs in the right order.
If there is a dependency cycle in the static initialization of a group of classes, then the order of initialization of the classes is indeterminate.
However, Java guarantees that default initialization of static fields (to null / zero / false) happens before any code gets to see the values of the fields. So a class can (in theory) be written to do the right thing irrespective of the initialization order.
Secondly, if the order is consistent, why would the lazy construction option ever be advantageous?
Lazy initialization is useful in a number of situations:
When the initialization has side effects that you don't want to happen unless the object is actually going to be used.
When the initialization is expensive, and you don't want it to waste time doing it unnecessarily ... or you want more important things to happen sooner (e.g. displaying the UI).
When the initialization depends on some state that is not available at static initialization time. (Though you need to be careful with this, because the state might not be available when lazy initialization gets triggered either.)
You can also implement lazy initialization using a synchronized getInstance() method. It is easier to understand, though it makes the getInstance() fractionally slower.
The code in the first version is the correct and best way to safely lazily construct a singleton.
The Java Memory Model guarantees that INSTANCE will:
Only be initialized when first actually used (ie lazy), because classes are loaded only when first used
Be constructed exactly once so it's completely thread-safe, because all static initialization is guaranteed to be completed before the class is available for use
Version 1 is an excellent pattern to follow.
EDITED
Version 2 is thread safe, but a little bit expensive and more importantly, severely limits concurrency/throughput
I'm not into your code snippet, but I have an answer for your question. Yes, Java has an initialization order fiasco. I came across it with mutually dependent enums. An example would look like:
enum A {
A1(B.B1);
private final B b;
A(B b) { this.b = b; }
B getB() { return b; }
}
enum B {
B1(A.A1);
private final A a;
B(A a) { this.a = a; }
A getA() { return a; }
}
The key is that B.B1 must exist when creating instance A.A1. And to create A.A1 B.B1 must exist.
My real-life use case was bit more complicated - the relationship between the enums was in fact parent-child so one enum was returning reference to its parent, but the second array of its children. The children were private static fields of the enum. The interesting thing is that while developing on Windows everything was working fine, but in production—which is Solaris—the members of the child array were null. The array had the proper size but its elements were null because they were not available when the array was instantiated.
So I ended up with the synchronized initialization on the first call. :-)
The only correct singletone in Java can be declared not by class, but by enum:
public enum Singleton{
INST;
... all other stuff from the class, including the private constructor
}
The use is as:
Singleton reference1ToSingleton=Singleton.INST;
All other ways do not exclude repeated instantiation through reflection or if the source of class is directly present in the app source. Enum excludes everything. ( The final clone method in Enum ensures that enum constants can never be cloned )
I'm trying to track down an issue in our system and the following code worries me. The following occurs in our doPost() method in the primary servlet (names have been changed to protect the guilty):
...
if(Single.getInstance().firstTime()){
doPreperations();
}
normalResponse();
...
The singleton 'Single' looks like this:
private static Single theInstance = new Single();
private Single() {
...load properties...
}
public static Single getInstance() {
return theInstance;
}
With the way this is set to use a static initializer instead of checking for a null theInstance in the getInstance() method, could this get rebuilt over and over again?
PS - We're running WebSphere 6 with the App on Java 1.4
I found this on Sun's site:
Multiple Singletons Simultaneously Loaded by Different Class Loaders
When two class loaders load a class,
you actually have two copies of the
class, and each one can have its own
Singleton instance. That is
particularly relevant in servlets
running in certain servlet engines
(iPlanet for example), where each
servlet by default uses its own class
loader. Two different servlets
accessing a joint Singleton will, in
fact, get two different objects.
Multiple class loaders occur more
commonly than you might think. When
browsers load classes from the network
for use by applets, they use a
separate class loader for each server
address. Similarly, Jini and RMI
systems may use a separate class
loader for the different code bases
from which they download class files.
If your own system uses custom class
loaders, all the same issues may
arise.
If loaded by different class loaders,
two classes with the same name, even
the same package name, are treated as
distinct -- even if, in fact, they are
byte-for-byte the same class. The
different class loaders represent
different namespaces that distinguish
classes (even though the classes'
names are the same), so that the two
MySingleton classes are in fact
distinct. (See "Class Loaders as a
Namespace Mechanism" in Resources.)
Since two Singleton objects belong to
two classes of the same name, it will
appear at first glance that there are
two Singleton objects of the same
class.
Citation.
In addition to the above issue, if firstTime() is not synchronized, you could have threading issues there as well.
No it won't get built over and over again. It's static, so it'll only be constructed once, right when the class is touched for the first time by the Classloader.
Only exception - if you happen to have multiple Classloaders.
(from GeekAndPoke):
As others have mentioned, the static initializer will only be run once per classloader.
One thing I would take a look at is the firstTime() method - why can't the work in doPreparations() be handled within the singleton itself?
Sounds like a nasty set of dependencies.
There is absolutely no difference between using a static initializer and lazy initialization. In fact it's far easier to mess up the lazy initialization, which also enforces synchronization. The JVM guarantees that the static initializer is always run before the class is accessed and it will happen once and only once.
That said JVM does not guarantee that your class will be loaded only once. However even if it is loaded more than once, your web application will still see only the relevant singleton, as it will be loaded either in the web application classloader or its parent. If you have several web application deployed, then firstTime() will be called once for each application.
The most apparent things to check is that firstTime() needs to be synchronized and that the firstTime flag is set before exiting that method.
No, It won't create multiple copies of 'Single'. ( Classloader issue will be visited later )
The implementation you outlined is described as 'Eager Initialization' by in Briant Goetz's book - 'Java Concurrency in Practice'.
public class Single
{
private static Single theInstance = new Single();
private Single()
{
// load properties
}
public static Single getInstance()
{
return theInstance;
}
}
However, the code is not you wanted. Your code is trying to perform lazy-initialization after the instance is created. This requires all the client library to perform 'firstTime()/doPreparation()' before using it. You are going to rely on the client to do right thing which make the code very fragile.
You can modify the code as the following so there won't be any duplicate code.
public class Single
{
private static Single theInstance = new Single();
private Single()
{
// load properties
}
public static Single getInstance()
{
// check for initialization of theInstance
if ( theInstance.firstTime() )
theInstance.doPreparation();
return theInstance;
}
}
Unfortunately, this is a poor implementation of lazy initialization and this will not work in concurrent environment ( like J2EE container ).
There are many articles written about Singleton initialization, specifically on memory model. JSR 133 addressed many weakness in Java memory model in Java 1.5 and 1.6.
With Java 1.5 & 1.6, you have several choices and they are mentioned in the book 'Effective Java' by Joshua Bloch.
Eager Initialziation, like the above [EJ Item 3]
Lazy Initalization Holder Class Idiom [EJ Item 71]
Enum Type [EJ Item 3]
Double Checked Locking with 'volatile' static field [EJ Item 71]
Solution 3 and 4 will only work in Java 1.5 and above. So the best solution would be #2.
Here is the psuedo-implementation.
public class Single
{
private static class SingleHolder
{
public static Single theInstance = new Single();
}
private Single()
{
// load properties
doPreparation();
}
public static Single getInstance()
{
return SingleHolder.theInstance;
}
}
Notice that 'doPreparation()' is inside of the constructor so you are guarantee to get the properly initialized instance. Also, you are piggying back on JVM's lazy class loading and do not need any synchronization 'getInstance()'.
One thing you noticed that static field theInstance is not 'final'. The example on Java Concurrency does not have 'final' but EJ does. Maybe James's can add more color to his answer on 'classloader' and requirement of 'final' to guarantee correctness,
Having said that, there are a side-effect that with using 'static final'. Java compiler is very aggressive when it sees 'static final' and tries to inline it as much as possible. This is mentioned on a blog posting by Jeremy Manson.
Here is a simple example.
file: A.java
public class A
{
final static String word = "Hello World";
}
file: B.java
public class B
{
public static void main(String[] args) {
System.out.println(A.word);
}
}
After you compile both A.java and B.java, you change A.java to following.
file: A.java
public class A
{
final static String word = "Goodbye World";
}
You recompile 'A.java' and rerun B.class. The output you would get is
Hello World
As for the classloader issue, the answer is yes, you can have more than one instance of Singleton in multiple classloaders. You can find more information on wikipedia. There is also a specific article on Websphere.
The only thing I would change about that Singleton implementation (other than not using a Singleton at all) is to make the instance field final. The static field will be initialised once, on class load. Since classes are loaded lazily, you effectively get lazy instantiation for free.
Of course, if it's loaded from separate class loaders you get multiple "singletons", but that's a limitation of every singleton idiom in Java.
EDIT: The firstTime() and doPreparations() bits do look suspect though. Can't they be moved into the constructor of the singleton instance?
No - the static initialization of the instance will only ever be done once. Two things to consider:
This is not thread-safe (the instance is not "published" to main memory)
Your firstTime method is probably called multiple times, unless properly synchronized
In theory it will be built only once. However, this pattern breaks in various application servers, where you can get multiple instances of 'singleton' classes (since they are not thread-safe).
Also, the singleton pattern has been critized a lot. See for instance Singleton I love you, but you're bringing me down
This will get only loaded once when the class is loaded by the classloader.
This example provides a better Singleton implementation however, it's as lazy-loaded as possible and thread-safe.
Moreover, it works in all known versions of Java.
This solution is the most portable across different Java compilers and virtual machines.
public class Single {
private static class SingleHolder {
private static final Single INSTANCE = new Single();
}
private Single() {
...load properties...
}
public static Single getInstance() {
return SingleHolder.INSTANCE;
}
}
The inner class is referenced no earlier (and therefore loaded no earlier by the class loader) than the moment that getInstance() is called. Thus, this solution is thread-safe without requiring special language constructs (i.e. volatile and/or synchronized).
It's not mandatory for the single instance to be final (it's not a good idea at all indeed, because this will avoid you to switch it's behaviour using other patterns).
In the code below you can see how it gets instantiated only once (first time you call the constructor)
package date;
import java.util.Date;
public class USDateFactory implements DateFactory {
private static USDateFactory usdatefactory = null;
private USDateFactory () { }
public static USDateFactory getUsdatefactory() {
if(usdatefactory==null) {
usdatefactory = new USDateFactory();
}
return usdatefactory;
}
public String getTextDate (Date date) {
return null;
}
public NumericalDate getNumericalDate (Date date) {
return null;
}
}