首页 > 代码库 > Java 单例模式

Java 单例模式

单例模式,1)静态变量来记录Singlegton类的唯一实例。2)私有构造方法。3)getInstance方法实例化对象,并返回这个实例。

1、先看看经典的单例模式写法 

 1 public class Singleton { 2     private static Singleton instance; 3     private Singleton(){ 4          5     } 6     public static Singleton getInstance(){ 7         if (instance==null) { 8             instance = new Singleton(); 9         }10         return instance;11     }12 }

看起来貌似没什么问题,其实不然,实际应用中,显然多线程同时访问时getInstance方法时,是有可能创建不同的实例的。

2、处理多线程的单例模式写法

 1 public class Singleton { 2     private static Singleton instance; 3     private Singleton(){ 4          5     } 6     public static synchronized Singleton getInstance(){ 7         if (instance==null) { 8             instance = new Singleton(); 9         }10         return instance;11     }12 }

通过增加synchronized关键字到getInstance方法中,可以解决多线程引发的创建不同实例的问题。但是同步会降低性能,这不是另一个问题么?

3、使用“急切”创建实例,而不是延迟实例化的做法

1 public class Singleton {2     private static Singleton instance = new Singleton();3     private Singleton(){4         5     }6     public static  Singleton getInstance(){7         return instance;8     }9 }

这种做法,我们依赖JVM在加载这个类时马上创建唯一的实例。JVM保证在任何线程访问instance之前,一定先创建此实例。但不推荐。建议“延迟实例化”(lazy instantiaze)

4、用“双重检查加锁”,在getInstace中减少使用同步(推荐)

 1 public class Singleton { 2     // volatile关键字确保:当instance变量被初始化Singleton实例时, 3     //多个线程能正确处理instance变量 4     private volatile static Singleton instance ; 5     private Singleton(){ 6          7     } 8     public static  Singleton getInstance(){ 9         if (instance==null) {10             synchronized (Singleton.class) {11                 if (instance==null) {12                     instance = new Singleton();13                 }14             }15         }16         return instance;17     }18 }

注意:关于双重加锁不适用 1.4及更早版本

如果性能是你关心的重点,那么这个做法可以帮你大大地减少getInstance的时间消耗。

Java 单例模式