134

Please clarify my queries regarding Singleton and Multithreading:

  • What is the best way to implement Singleton in Java, in a multithreaded environment?
  • What happens when multiple threads try to access getInstance() method at the same time?
  • Can we make singleton's getInstance() synchronized?
  • Is synchronization really needed, when using Singleton classes?
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
RickDavis
  • 2,276
  • 6
  • 25
  • 31

8 Answers8

235

Yes, it is necessary. There are several methods you can use to achieve thread safety with lazy initialization:

Draconian synchronization:

private static YourObject instance;

public static synchronized YourObject getInstance() {
    if (instance == null) {
        instance = new YourObject();
    }
    return instance;
}

This solution requires that every thread be synchronized when in reality only the first few need to be.

Double check synchronization:

private static final Object lock = new Object();
private static volatile YourObject instance;

public static YourObject getInstance() {
    YourObject r = instance;
    if (r == null) {
        synchronized (lock) {    // While we were waiting for the lock, another 
            r = instance;        // thread may have instantiated the object.
            if (r == null) {  
                r = new YourObject();
                instance = r;
            }
        }
    }
    return r;
}

This solution ensures that only the first few threads that try to acquire your singleton have to go through the process of acquiring the lock.

Initialization on Demand:

private static class InstanceHolder {
    private static final YourObject instance = new YourObject();
}

public static YourObject getInstance() {
    return InstanceHolder.instance;
}

This solution takes advantage of the Java memory model's guarantees about class initialization to ensure thread safety. Each class can only be loaded once, and it will only be loaded when it is needed. That means that the first time getInstance is called, InstanceHolder will be loaded and instance will be created, and since this is controlled by ClassLoaders, no additional synchronization is necessary.

mfb
  • 833
  • 10
  • 14
Jeffrey
  • 44,417
  • 8
  • 90
  • 141
  • 26
    Warning - be careful with double-checked synchronization. It doesn't work properly with pre-Java 5 JVMs due to "issues" with the memory model. – Stephen C Jun 23 '12 at 03:06
  • 3
    -1 `Draconian synchronization` and `Double check synchronization` getInstance()-method must be static! – Grim Sep 29 '13 at 09:58
  • 2
    @PeterRader They don't *need* to be `static`, but it might make more sense if they were. Amended as requested. – Jeffrey Sep 29 '13 at 17:26
  • @PeterRader The same pattern would be used for any object that needs thread safe lazy instantiation. – Jeffrey Sep 30 '13 at 23:23
  • What about notifyAll() on the lock?? – Nativ Oct 09 '13 at 11:03
  • @powerX Why would I need to worry about that? I am never calling `wait` on the lock. – Jeffrey Oct 10 '13 at 01:18
  • Ah, I'm assumed wrong that other threads are waiting when they are getting to the synchronized(lock), and that notifyAll() is the this that is waking them. – Nativ Oct 10 '13 at 08:41
  • What are the disadvantages of the last method? or, what are the advantages of the others over it? – android developer Apr 27 '14 at 14:28
  • 1
    @androiddeveloper The advantage of the last method is its simplicity. Its disadvantage is that you have to make a separate class. You will have an extra *.class file and class loading is also not a free operation. – Jeffrey Apr 27 '14 at 14:58
  • @Jeffrey but you can just put it all in the same class, and then I can't find any disadvantage. it's on demand, thread safe, very fast, very easy,... – android developer Apr 27 '14 at 16:14
  • 1
    @androiddeveloper In order for initialization on demand to work, the holder *must* be a separate **`static`** inner class, otherwise it will not work. This will generate another *.class file at compilation time, and a class loading overhead when you first access your singleton. – Jeffrey Apr 27 '14 at 16:26
  • @Jeffrey I meant the one called "Eager initialization" on wikipedia here: http://en.wikipedia.org/wiki/Singleton_pattern – android developer Apr 27 '14 at 16:37
  • @androiddeveloper Ah. All of the examples in my answer use [lazy evaluation](https://en.wikipedia.org/wiki/Lazy_evaluation) (the opposite is [eager evaluation](https://en.wikipedia.org/wiki/Eager_evaluation)). [Lazy evaluation can be more efficient](http://stackoverflow.com/q/265392/758280) in the situation where you might not need to use the singleton. – Jeffrey Apr 27 '14 at 17:19
  • @Jeffrey But if you won't use the singleton, you won't reach the code and the instance won't be created, so it's a win-win, no? The way I remember it is that as soon as you reach the singleton class (a bit before the real call to getInstance) , the static reference is filled with the new instance. – android developer Apr 27 '14 at 20:43
  • 1
    @androiddeveloper Sometimes the singleton pattern is implemented as a part of a larger more complex object. Let's say an object has two main tasks: the first task which is unrelated to the singleton, and the second task. If you use an object for only the first task while using eager initialization, you will waste time and resources creating the singleton which you will not use. – Jeffrey Apr 28 '14 at 03:06
  • @Jeffrey but in both cases you will need to instantiate it and waste time and resources, since you need to perform the task... – android developer Apr 28 '14 at 05:19
  • 1
    @androiddeveloper There are some cases where it is not a guarantee that you want to use the resource. Or maybe you want to delay instantiating the resource until when you need it so that you have a faster start up time. – Jeffrey Apr 28 '14 at 15:25
  • @Jeffrey But if you don't use it, why call it? right when you start using it, it will get instantiated. – android developer Apr 28 '14 at 16:27
  • this may be a stupid question, but where does your lock object come from? – Alex Lehmann May 17 '14 at 17:14
  • 4
    You're implementation of double checked locking isn't guaranteed to work. It's actually explained in the article you cited for double checked locking. :) There is an example in there using volatile that works properly for 1.5 and higher (double checked locking is just plain broken below 1.5). The initialization on demand holder also cited in the article would probably be a simpler solution in your answer. – stuckj May 08 '15 at 16:05
  • @stuckj I'm aware. However, I have yet to run into a single instance where I was running on anything before Java 1.6, so it's safe to say that it will work correctly. – Jeffrey May 08 '15 at 22:41
  • I think this **lock** object is unnecessary. Why not synchronize on the YourObject.class itself.? – Witold Kaczurba Sep 19 '17 at 10:10
  • 1
    @Vito because anyone can synchronize on `YourObject.class`. It's always safer to use a private lock object because then you know exactly when and where the monitor will be grabbed – Jeffrey Sep 19 '17 at 12:31
  • why `InstanceHolder` must be a separate class? `public class Foo { private static Foo f = new Foo(); public static Foo getInstance() {return f;}` What's wrong with this? – Tiina Mar 23 '18 at 01:55
  • @Tiina That will work for eagerly initialized singletons, but if you want a lazily loaded singleton you'll probably want to use [Initialization on Demand](https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom) – Jeffrey Mar 23 '18 at 13:15
  • Why do we need 'r'? Why can we just use - public static YourObject getInstance() { if (instance == null) { synchronized (lock) { if (instance == null) { instance = new YourObject(); } } } return instance; } Please excuse the formatting. What I have typed above is the one in the answer by Dan Moldovan – MediumOne Jan 02 '19 at 10:28
  • 2
    @MediumOne AFAIK, `r` is not needed for correctness. It's just an optimization to avoid accessing the volatile field, since that's far more expensive than accessing a local variable. – Jeffrey Jan 02 '19 at 13:56
  • Doesn't the `synchronized` block ensure that the non-cached values of the fields will be retrieved, meaning that the `volatile` part is not needed anymore ? Is this still required even today? – android developer Jan 27 '21 at 14:17
  • @androiddeveloper Entering a `synchronized` block is more expensive than accessing a `volatile` variable. Making the variable `volatile` means we get to skip entering the `synchronized` block at all after the singleton has been initialized. – Jeffrey Jan 27 '21 at 15:26
  • @Jeffrey So the `volatile` is only good for performance of first access , and not for better thread-safety as I've read on some places? Also, isn't this a relatively tiny boost, as it's only for current threads, and only for the case that they are before the synchronized part and it's being updated now? Meaning it's a very specific thing, no? – android developer Jan 27 '21 at 15:56
  • @androiddeveloper I'd recommend reading through the wiki page I linked to above if you want all the nitty gritty details. We need `volatile` to ensure thread safety/memory consistency. It's good for performance for all accesses after the singleton has been initialized. It is not a tiny boost. – Jeffrey Jan 28 '21 at 03:03
  • @Jeffrey But then it's not only for performance, no? – android developer Jan 28 '21 at 07:15
  • @androiddeveloper You could have a solution that _always_ synchronized. That solution would be correct, but pretty slow. We use `volatile` to improve the performance of a such a solution while ensuring thread safety. – Jeffrey Jan 28 '21 at 19:17
  • @Jeffrey I understand, but with the double check, is it indeed needed to use volatile for thread safety ? I wonder if using AtomicReference is also the same – android developer Jan 29 '21 at 20:51
  • If the singleton initialization needs to eventually call a web service or fetch from a database, where do you place this code? Do you put it inside the singleton class or outside? Can you please point me to examples. – tarekahf Apr 18 '23 at 08:36
  • @tarekahf that opens up a whole other can of worms: How do you handle retries? If your singleton initialization logic could fail, you need to handle the case where it will fail. Potentially permanently. I don't know of any simple examples I can point you to, but I know some server frameworks have systems where you can tell it to retry initializing your singleton until it succeeds, and it won't start your server until it does. And if this isn't a server use case, you can accomplish something similar yourself by writing that retry loop before executing the CLI command. – Jeffrey Apr 19 '23 at 00:09
  • I have already developed the retry logic and embedded it along with the singleton initialization and web service invocation. Check my recent questions. – tarekahf Apr 19 '23 at 06:16
  • what is the importance of a null check when the call is already synchronized in Draconian synchronization? – iabhishek15 Jul 06 '23 at 16:17
  • @iabhishek15 You typically only want to initialize singletons exactly once. Otherwise, why bother with a singleton at all? You could just create a new object every time you needed its functionality. – Jeffrey Jul 12 '23 at 04:15
82

This pattern does a thread-safe lazy-initialization of the instance without explicit synchronization!

public class MySingleton {

     private static class Loader {
         static final MySingleton INSTANCE = new MySingleton();
     }

     private MySingleton () {}

     public static MySingleton getInstance() {
         return Loader.INSTANCE;
     }
}

It works because it uses the class loader to do all the synchronization for you for free: The class MySingleton.Loader is first accessed inside the getInstance() method, so the Loader class loads when getInstance() is called for the first time. Further, the class loader guarantees that all static initialization is complete before you get access to the class - that's what gives you thread-safety.

It's like magic.

It's actually very similar to the enum pattern of Jhurtado, but I find the enum pattern an abuse of the enum concept (although it does work)

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 13
    Synchronization is still present, it's just enforced by the JVM instead of by the programmer. – Jeffrey Jun 23 '12 at 01:11
  • @Jeffrey You're right of course - I was typing it all in (see edits) – Bohemian Jun 23 '12 at 01:13
  • Why not add an explicit "final" qualifier to the declaration of INSTANCE? Took me a while to sort it out without it. – Irina Rapoport Oct 23 '14 at 06:57
  • @ТаняТ. There's nothing to sort out. It's a private class so nothing else has access to it and it's initialized statically. Make it final if you want, but it won't make any difference to the safety or behaviour. – Bohemian Oct 23 '14 at 07:05
  • 2
    I understand it makes no difference to the JVM, I am just saying it made a difference to me as far as self-documented code goes. I've just never seen all caps in Java without the "final" keyword before (or enum), got a bit of cognitive dissonance. For someone programming Java full time, it probably would not make a difference, but if you jump languages back and forth, it helps to be explicit. Ditto for newbies. Although, I am sure one can adapt to this style pretty quick; all caps is probably enough. Don't mean to nit pick, I liked your post. – Irina Rapoport Oct 23 '14 at 16:23
  • 1
    Excellent answer, though I didn't get some part of it. Can you elaborate "Further, the class loader guarantees that all static initialization is complete before you get access to the class - that's what gives you thread-safety." , how that helps in thread safety, I'm a little confused about that. – gaurav jain Dec 26 '14 at 18:33
  • Why not `static final MySingleton INSTANCE`? – wz366 Sep 27 '17 at 17:50
  • 2
    @wz366 actually, although it's not necessary, I agree for style reasons (since it is effectively final because no other code can access it) `final` should be added. Done. – Bohemian Sep 27 '17 at 18:11
  • 1
    How would I pass an argument to the ``MySingleton`` constructor inside the inner class if the ``getInstance`` method requires a parameter? – Robur_131 Aug 17 '19 at 20:47
  • @Robur_131 do you want `public static MySingleton getInstance(Object param) {...}`? – Bohemian Aug 17 '19 at 23:29
  • Yes. How would I pass ``param`` to ``MySingleton`` if the constructor requires ``param``? – Robur_131 Aug 17 '19 at 23:37
  • @robur will the parameter be the same for all calls? If not, should a different instance be returned for each distinct parameter value? Or, if the parameter is effectively a constant, can it be known when the class is loaded? I need a lot more detail about the parameter value, its influence and lifecycle in order to answer your question (and depending on your clarification, may be more appropriate to ask In its own separate question) – Bohemian Aug 18 '19 at 11:41
  • @Bohemian Why is this impl. called lazy initialization when JVM is going to do it? I thought lazy meant when an instance is not created apriori. – veritas Dec 11 '20 at 19:55
  • @veritas “lazy” means “left until actually needed for use”. This specific code pattern has a name: [Initialization-on-demand holder idiom](https://en.m.wikipedia.org/wiki/Initialization-on-demand_holder_idiom). Read that article for a more complete explanation. – Bohemian Dec 11 '20 at 22:54
22

If you are working on a multithreaded environment in Java and need to gurantee all those threads are accessing a single instance of a class you can use an Enum. This will have the added advantage of helping you handle serialization.

public enum Singleton {
    SINGLE;
    public void myMethod(){  
    }
}

and then just have your threads use your instance like:

Singleton.SINGLE.myMethod();
jhurtado
  • 8,587
  • 1
  • 23
  • 34
10

Yes, you need to make getInstance() synchronized. If it's not there might arise a situation where multiple instances of the class can be made.

Consider the case where you have two threads that call getInstance() at the same time. Now imagine T1 executes just past the instance == null check, and then T2 runs. At this point in time the instance is not created or set, so T2 will pass the check and create the instance. Now imagine that execution switches back to T1. Now the singleton is created, but T1 has already done the check! It will proceed to make the object again! Making getInstance() synchronized prevents this problem.

There a few ways to make singletons thread-safe, but making getInstance() synchronized is probably the simplest.

Oleksi
  • 12,947
  • 4
  • 56
  • 80
  • Will it help by putting object creation code in Synchronized block, instead of making entire method synchronization? – RickDavis Jun 23 '12 at 00:54
  • @RaoG No. You want both the check _and_ the creation in the synchronization block. You need those two operations happen together without interruptions or the situation I described above may happen. – Oleksi Jun 23 '12 at 00:56
7

Enum singleton

The simplest way to implement a Singleton that is thread-safe is using an Enum

public enum SingletonEnum {
  INSTANCE;
  public void doSomething(){
    System.out.println("This is a singleton");
  }
}

This code works since the introduction of Enum in Java 1.5

Double checked locking

If you want to code a “classic” singleton that works in a multithreaded environment (starting from Java 1.5) you should use this one.

public class Singleton {

  private static volatile Singleton instance = null;

  private Singleton() {
  }

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

This is not thread-safe before 1.5 because the implementation of the volatile keyword was different.

Early loading Singleton (works even before Java 1.5)

This implementation instantiates the singleton when the class is loaded and provides thread safety.

public class Singleton {

  private static final Singleton instance = new Singleton();

  private Singleton() {
  }

  public static Singleton getInstance() {
    return instance;
  }

  public void doSomething(){
    System.out.println("This is a singleton");
  }

}
realPK
  • 2,630
  • 29
  • 22
Dan Moldovan
  • 371
  • 3
  • 3
2

You can also use static code block to instantiate the instance at class load and prevent the thread synchronization issues.

public class MySingleton {

  private static final MySingleton instance;

  static {
     instance = new MySingleton();
  }

  private MySingleton() {
  }

  public static MySingleton getInstance() {
    return instance;
  }

}
usha
  • 28,973
  • 5
  • 72
  • 93
  • @Vimsha A couple other things. 1. You should make `instance` final 2. You should make `getInstance()` static. – John Vint Jun 12 '14 at 19:06
  • What would you do if you want to create a thread in the singleton. – Arun George Jan 29 '15 at 08:58
  • @arun-george use a thread pool, a single thread pool if needed, and surround with a while(true)-try-catch-throwable if you want to ensure your thread never dies, no matter what error? – tgkprog Feb 06 '15 at 15:41
0

What is the best way to implement Singleton in Java, in a multithreaded environment?

Refer to this post for best way to implement Singleton.

What is an efficient way to implement a singleton pattern in Java?

What happens when multiple threads try to access getInstance() method at the same time?

It depends on the way you have implemented the method.If you use double locking without volatile variable, you may get partially constructed Singleton object.

Refer to this question for more details:

Why is volatile used in this example of double checked locking

Can we make singleton's getInstance() synchronized?

Is synchronization really needed, when using Singleton classes?

Not required if you implement the Singleton in below ways

  1. static intitalization
  2. enum
  3. LazyInitalaization with Initialization-on-demand_holder_idiom

Refer to this question fore more details

Java Singleton Design Pattern : Questions

Community
  • 1
  • 1
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
0
public class Elvis { 
   public static final Elvis INSTANCE = new Elvis();
   private Elvis () {...}
 }

Source : Effective Java -> Item 2

It suggests to use it, if you are sure that class will always remain singleton.

Ashish
  • 735
  • 1
  • 6
  • 15