Java单例模式Singleton

早上大马路就在施工,闹腾的睡不着。

关于单例模式,一开始以为很简单,一直都是这样写的:

public class Singleton{
     public static Singleton instance = null;

     private Singleton(){
     }

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

 
正巧最近在看Java相关的多线程、并发。也有人在网上说了这个问题。上边的这个法子不是线程安全的!

所以改呗。加个synchronized不就行了呗。

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

 
这样肯定就行了。不过唯一麻烦的是在大量调用Singleton.getInstance()的时候可能会有性能问题

再改,在里边加锁

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

 
把锁加到instance为null的条件中,这样就快多了。然后里边还得再加个判断。这样其他县城再调用的时候instance已经初始化就不用再new了。。。。网上把这个叫做double-checked locking

还有没有其他的法子?干脆就在声明类的时候直接初始化不就行了!?于是有了个:

 

public class Singleton{
     public static final Singleton INSTANCE = new Singleton();

     private Singleton(){
     }

     public static Singleton getInstance(){
          return INSTANCE;
     }
} 

 
这样就行了。不过网上说在这个累初始化消耗不大的时候可以这样用。PS:加上了final就是不可变的了。

最后找的麻烦,直接上维基百科(https://en.wikipedia.org/wiki/Singleton_pattern)。发现前边的例子都有,而且还提供了两个更狂燥的例子。

例子1:

public class Singleton{
     public static class SingletonHolder(){
          private static final Singleton INSTANCE = new Singleton();
     }

     private Singleton(){
     }

     public static Singleton getInstance(){
          return SingletonHolder.INSTANCE;
     }
}

 
貌似这是因为Java虚拟机在这样处理内部类的时候会保证线程安全。而且据称在所有版本的JVM下都可以搞得定。

例子2:

public enum Singleton{
     INSTANCE;

     public void doSomeThing(){
          // ...
     }
}

 
有些简单的过了。。。。。用的居然是Enum!!!然后用的时候直接Singleton.INSTANCE就可以了!!!不过貌似要在JDK5以上才能支持,而且支持的原因很简单。JDK5以后枚举里创建对象是线程安全的。。。。《Effect Java》里就是这样搞的。。。。

你可能感兴趣的:(Singleton)