Java Singleton and Sync

Please clarify my queries regarding Singleton and Multithreading:

  • What is the best way to implement Singleton in Java, in a multi-threaded environment?
  • What happens when multiple threads try to access the getInstance() method at the same time?
  • Can we make singleton getInstance() synchronized ?
  • Is synchronization necessary when using Singleton classes?
+86
java multithreading synchronization singleton
Jun 23 2018-12-12T00:
source share
8 answers

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

Draconian Sync:

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

This solution requires that each thread be synchronized, when in fact there should be only the first few.

Double sync check :

 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 must go through the blocking process.

Initialization upon request :

 private static class InstanceHolder { private static final YourObject instance = new YourObject(); } public static YourObject getInstance() { return InstanceHolder.instance; } 

This solution uses a Java memory model that guarantees class initialization to ensure thread safety. Each class can be loaded only once, and it will be loaded only when necessary. This means that the first call to getInstance will load the InstanceHolder and create an instance , and since this is controlled by ClassLoader s, no additional synchronization is required.

+163
Jun 23 '12 at 1:01
source share

This template performs thread-initialization of a stream without using 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 MySingleton.Loader class first accesses the getInstance() method, so the Loader class is loaded when getInstance() is called for the first time. In addition, the class loader ensures that all static initialization is complete before you access the class - which gives you thread safety.

It looks like magic.

It really looks a lot like the Jhurtado enumeration pattern, but I find the enumeration pattern as an abuse of the enum concept (although it does work)

+49
Jun 23 2018-12-12T00:
source share

If you are working on a multi-threaded Java environment and you must ensure that all of these threads access the same instance of the class, you can use Enum. This will have the added benefit of helping you deal with serialization.

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

and then just your threads will use your instance, for example:

 Singleton.SINGLE.myMethod(); 
+19
Jun 23 '12 at 1:01
source share

Yes, you need to do getInstance() synchronization. If this is not the case, a situation may arise when several instances of the class can be made.

Consider the case where you have two threads that call getInstance() at the same time. Now imagine that T1 only runs after checking instance == null , and then T2 starts. At the moment, the instance is not created or not installed, 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 already checked! He will begin to make the object again! Performing getInstance() synchronization prevents this problem.

There are several ways to make threads in singleton threads, but getInstance() synchronization is probably the easiest.

+8
Jun 23 2018-12-12T00:
source share

Enum singleton

The easiest way to implement Singleton, which is thread safe, is to use Enum

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

This code has been working since Enum appeared in Java 1.5

Double check lock

If you want to encode a β€œclassic” singleton that works in a multi-threaded environment (since 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 until 1.5, because the implementation of the volatile keyword is different.

Singleton early boot (works even before Java 1.5)

This implementation creates a singleton instance when the class loads 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"); } } 
+5
Oct 02 '15 at 11:35
source share

You can also use a static code block to instantiate the instance when loading the class and prevent thread synchronization problems.

 public class MySingleton { private static final MySingleton instance; static { instance = new MySingleton(); } private MySingleton() { } public static MySingleton getInstance() { return instance; } } 
+2
Jun 12 '14 at 18:44
source share

What is the best way to implement Singleton in Java in a multi-threaded environment?

Refer to this post for a better way to implement Singleton.

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

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

It depends on how the method is implemented. If you use double locking without a mutable variable, you can get a partially constructed Singleton object.

Refer to this question for more information:

Why volatility is used in this example of double locking lock

Is it possible to make singleton getInstance () synchronized?

Do I really need synchronization when using Singleton classes?

Not required if you are implementing Singleton below ways

  • static intinalization
  • enum
  • LazyInitalaization with Initialization-on-demand_holder_idiom

See this question for more details.

Java Singleton Design Pattern: Questions

0
Jun 27. '16 at 9:30
source share
 public class Elvis { public static final Elvis INSTANCE = new Elvis(); private Elvis () {...} } 

Source: Effective Java β†’ Point 2

It is suggested to use it if you are sure that the class will always remain single.

0
Jan 02 '17 at 22:18
source share



All Articles