Is this a good implementation for a Thread Safe Lazily Loaded Singleton in Java?

蓝咒 提交于 2019-12-23 00:29:08

问题


I want to implement Thread Safe Lazily Loaded Singleton in Java.

Is this a good design?

public final class ThreadSafeLazySynchronizedSingleton {

private ThreadSafeLazySynchronizedSingleton(){}

private static ThreadSafeLazySynchronizedSingleton instance;

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

}

I also want to create a lock-less version for use in a scenario where one thread accesses the Singleton many more times than the other threads, how would I achieve this using the atomic objects in Java, ie AtomicBoolean or AtomicReference etc. Could you provide a code example please?


回答1:


A better design would be

public final class ThreadSafeLazySynchronizedSingleton {

    private ThreadSafeLazySynchronizedSingleton(){}

    private static volatile ThreadSafeLazySynchronizedSingleton instance;

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

However, the best design IMHO is

public enum ThreadSafeLazySynchronizedSingleton {
    INSTANCE;
}



回答2:


The recommended approach to implementing Singleton design pattern in Java is using the Enum approach. The Enum approach is very simple and thread safe implicitly.

public enum EnumTest {
  INSTANCE;

  // Test code
  public static void main(String[] args) {

      // First thread
      Thread t1 = new Thread(new Runnable() {
         @Override
         public void run() {
             EnumTest obj = EnumTest.INSTANCE;
         }   
      });
      t1.start();

      // Second thread
      Thread t2 = new Thread(new Runnable() {
         @Override
         public void run() {
             EnumTest obj = EnumTest.INSTANCE;
         }   
      });  
      t2.start();
   }
 }

Nice tutorial here.




回答3:


The simplest thing will probably be as lazy as you need it:

private static ThreadSafeLazySynchronizedSingleton instance
    = new ThreadSafeLazySynchronizedSingleton();

public static ThreadSafeLazySynchronizedSingleton instance() {
    return instance;
}

True, instance will be created as soon as the class is loaded. But the class won't be loaded until it's used, and at that point you probably need to get the instance, anyway.

The only time this wouldn't be as lazy as you need is if the ThreadSafeLazySynchronizedSingleton class also had static helper methods that don't use instance, but that would suggest they don't have much to do with the rest of the class and should probably be moved to their own class.

A lot of people also use a single-value enum for singletons. Personally I find it ugly, but it does have some advantages (handles the private constructor and instance for you, and the singleton-ness is enforced even if your class is serializable, which is otherwise not trivial).




回答4:


If you wanted a true lock-free implementation it would require some spinning. Otherwise @yshavit or @Peter Lawrey are the best possible answers.

Lock Free:

private static final AtomicBoolean created = new AtomicBoolean(false);
private static volatile LazySingleton instance = null;

public static ThreadSafeLazySynchronizedSingleton getIntsance(){
   if(instance != null) return instance.get();

   if(created.compareAndSet(false, true)){
      //only one thread can try and create
      instance = new LazySingleton();
   } else {
      //other thread is creating, spin until ready
      while(instance == null);
   }
   return instance;
}


来源:https://stackoverflow.com/questions/24434566/is-this-a-good-implementation-for-a-thread-safe-lazily-loaded-singleton-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!