views:

825

answers:

6

I am implementing a singleton class in Java to make sure no more than one instance of the class is created.

A: 

Singletons are not threadsafe per default. The common way to create a singleton is to have a factory method that handles creation of the one instance. That way you can control instance creation.

Brian Rasmussen
+2  A: 
public class Singleton {
  public static final Singleton INSTANCE = new Singleton();
  private Singleton() { ... }
}

Using a static instance variable is preferred to the internal "Holder" class. If you like, you can also make the static member private and provide a method for accessing it, but all that does is add another method call to the stack.

Tim Bender
It rather depends what you're trying to achieve as to what is preferred - the holder gives you a lazy singleton, the simpler version doesn't give you lazy loading.
Pete Kirkham
Yes, it does. Java doesn't load classes until they're first used.
Michael Borgwardt
Not entirely true. It loads them when they're first referenced, e.g. in the method signature of another class.
skaffman
Accessor methods are normally inlined by the VM. Do not choose public field over accessor to get rid of a "method call on the stack" - in your code, it will look like a method call, but in reality, it'll be the same thing.
gustafc
A: 

What about lazy instanciation: getInstance() returns the singleton or create it if it is the first call.

 public class MySingleton
 {
     private static MySingleton instance;

     private MySingleton()
     {
         // construct object . . .
     }

     // For lazy initialization
     public static synchronized MySingleton getInstance()
     {
         if (instance==null)
         {
             instance = new MySingleton();
         }
         return instance;
     }

     // Remainder of class definition . . .
 }
enguerran
Lazy instantiation is almost never necessary, and if it is, Java loads classes lazily, so creating the instance in the declaration actually *is* lazy instantiation - without synchronization overhead (in very rare cases that's not lazy enough and skaffman's answer is better).
Michael Borgwardt
Also note this implementation synchronizes every attempt to obtain a reference to the instance. Since most code will do something like:Singleton.getInstance.doSomething();Singleton.getInstance.doSomethingElse();The overall effect would be additional synchronization severely limiting concurrency with no thread safety guarantees in terms of member access/mutation.
Tim Bender
Double-checked locking in java is broken http://www.javaworld.com/jw-02-2001/jw-0209-double.htmlIn short, this way of guaranteeing that this class is instantiated only once may result in hard-to-find concurrency issues. Never use this.
Buhb
DCL is non-broken as of Java 5. Check out http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html, scroll down to "Under the new Java Memory Model".
gustafc
+10  A: 

The best way to make a singleton? Use an enum.

public enum Singleton {
    INSTANCE;
    public void foo(){ ... }
}

// Usage:
Singleton.INSTANCE.foo();

You get lots of help from the VM not only to avoid double instantiation, but it also helps you avoid deserialization corruption.

gustafc
A: 

If you care about concurrency, you won't be using shared global state.

jrockway
If the singleton holds the accumulation of results from a singular parallelized problem why not? A singleton epitomizes global state, and as such it would be a fair usage scenario.
_ande_turner_
There are several use cases for classes represented with only one instance that is shared between processes. A typical well designed webapp using spring will probably have a bunch of classes instantiated in singleton scope, shared between worker threads.
Buhb
+4  A: 

Perhaps the best way is to use an enum with a single instance. This has the added benefit of being serializable and guaranteeing singleton-ness against serialization and reflection, which no "straightforward" Singleton implementation does (private? I have reflection, I scoff derisively at your access modifiers!). It's also very simple to implement:

public enum Singleton {
    INSTANCE;

    // fields and methods go here
}
Michael Borgwardt