-1

As we know for synchronous operation while creating singleton class we make whole method as synchronized or only block of statements which are responsible for creation of object as synchronized.But, among these two approaches which one is better and why?

Approach 1

public static A getA(){  
    if (obj == null){  
        synchronized(Singleton.class) {
            if (obj == null) {
                obj = new Singleton();//instance will be created at request time  
            }  
        }   
    }  
    return obj;  
} 

Approach 2

public synchronized static A getA(){  
    if (obj == null){  
        obj = new Singleton();//instance will be created at request time  
    }   
    return obj;  
} 
Ele
  • 31,191
  • 6
  • 31
  • 67
Sritam Jagadev
  • 871
  • 3
  • 14
  • 36
  • it doesn't matter because Singletons are bad anyways – Sleiman Jneidi Dec 26 '17 at 12:46
  • 1
    @SleimanJneidi Just curious, why singletons are bad? – Akashdeep Saluja Dec 26 '17 at 12:48
  • ya i know that but, could you please explain me which approach is better among these two? – Sritam Jagadev Dec 26 '17 at 12:48
  • I think your approach 1 will be problematic. Since the thread can be stopped after the if condition is checked and before entering into the synchronize block – Rodolfo Dec 26 '17 at 12:51
  • @SleimanJneidi why singletons are bad? – Ele Dec 26 '17 at 12:58
  • @Rodolfo I need a confident answer with proper explanation. because basing upon this concept i am going to write a enterprise application model.please help – Sritam Jagadev Dec 26 '17 at 12:58
  • Please consider not writing enterprise application model that is based on singletons. – M. Prokhorov Dec 26 '17 at 13:04
  • Check this thread for pros and cons of singleton: https://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons – Ivan Dec 26 '17 at 14:27
  • Please do not do that. your model should not have any singletons. Consider singletons only for objects like DB connections or logging. In general consider using so little singleton as possible, since they are hidden global variables. – Rodolfo Dec 26 '17 at 14:32

4 Answers4

1

The first one is better because you don't acquire the lock when obj is not null, while the second approach acquires the lock each time.

Nikita Gorbachevski
  • 1,998
  • 5
  • 14
1

Concept:

public synchronized static A getA(){  
    if (obj == null){  
        obj = new Singleton();//instance will be created at request time  
    }   
    return obj;  
} 

Using the synchronization keyword on a method (like in the example above) synchronizes access to that entire method, which is generally pretty safe but unless you have a very small method you may be synchronizing a bigger chunk of code than you absolutely need to, which is more of a performance hit than necessary. Because synchronized blocks/methods can only be accessed by one thread at a time, they really slow down processing. The larger a chunk of code you synchronize, the worse the performance hit is.

If you require only a single resource that is lazy loaded, you need to do something like this:

class MyClass {
      private static volatile Resource resource;
      private static final Object LOCK = new Object();

      public static Resource getInstance() {
            if(resource == null) { 
                synchronized(LOCK) { // Add a synch block
                    if(resource == null) { // verify some other synch block didn't
                                           // write a resource yet...
                        resource = new Resource();
                    }
                }
            }
            return resource;
      }
 }

One important thing here is the volatile modifier providing visibility for the whole threads in your app.

Ele
  • 31,191
  • 6
  • 31
  • 67
1

I would take the first one, which has a double checked locking.

Maybe you can also try something like this:

public class MySingleton {
       private static instance = new MySingleton ();
       private MySingleton (){ }
       public MySingleton getInstance {
            return instance;
       }
 }
1

You'd better use Holder idiom

public class HolderFactory {
   public static Singleton get() {
      return Holder.instance;
   }

   private static class Holder {
     public static final Singleton instance = new Singleton();
   }
}

It is lazy because instance will be created upon first call to get() and it is thread-safe because class is guaranteed to be loaded by classloader in a single thread. You could also check this link for more details regarding singletons and thread-safety: https://shipilev.net/blog/2014/safe-public-construction/

Ivan
  • 7,770
  • 2
  • 17
  • 25