java设计模式_单例模式
懒汉式 非线程安全
特点:Lazy 初始化、非多线程安全、易实现
描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。
1 public class Singleton { 2 private static Singleton instance; 3 4 //私有化构造器,不让其他类来创建对象 5 private Singleton (){} 6 7 //静态工厂,专门用来生产类的实例 8 public static Singleton getInstance() { 9 if (instance == null) { 10 instance = new Singleton(); 11 } 12 return instance; 13 } 14 }
懒汉式 线程安全
Lazy 初始化、多线程安全、易实现
描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
1 public class Singleton { 2 private static Singleton instance; 3 private Singleton (){} 4 public static synchronized Singleton getInstance() { //synchronized 5 if (instance == null) { 6 instance = new Singleton(); 7 } 8 return instance; 9 } 10 }
饿汉式
非 Lazy 初始化、多线程安全、易实现
描述:这种方式比较常用,但容易产生垃圾对象。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
它基于 classloader 机制避免了多线程的同步问题。
1 public class Singleton { 2 private static Singleton instance = new Singleton(); 3 private Singleton (){} 4 public static Singleton getInstance() { 5 return instance; 6 } 7 }
双检锁(DCL,即 double-checked locking)
JDK 版本:JDK1.5 起
Lazy 初始化、多线程安全、较复杂
描述:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
getInstance() 的性能对应用程序很关键。
1 public class Singleton { 2 private volatile static Singleton singleton; 3 private Singleton (){} 4 public static Singleton getSingleton() { 5 if (singleton == null) { 6 synchronized (Singleton.class) { 7 if (singleton == null) { 8 singleton = new Singleton(); 9 } 10 } 11 } 12 return singleton; 13 } 14 }
登记式/静态内部类
Lazy 初始化、多线程安全
描述:这种方式能达到双检锁方式一样的功效,但实现更简单。对静态域使用延迟初始化,应使用这种方式而不是双检锁方式。这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。
1 public class Singleton { 2 private static class SingletonHolder { 3 private static final Singleton INSTANCE = new Singleton(); 4 } 5 private Singleton (){} 6 public static final Singleton getInstance() { 7 return SingletonHolder.INSTANCE; 8 } 9 }
一个小例子
1 public class SinglTon { 2 3 private static SinglTon instance = null; 4 5 //私有化构造器,不让其他类创建对象 6 private SinglTon() { 7 8 } 9 10 //静态工厂,专门用来生产类的实例 11 public static SinglTon getInstance() { 12 if(instance == null) { 13 instance = new SinglTon(); 14 } 15 // 16 return instance; 17 } 18 19 public void say() { 20 System.out.println("我只有一个"); 21 } 22 }
来个测试类:
1 public class SinglTonT { 2 3 public static void main(String[] args) { 4 SinglTon s2 =SinglTon.getInstance(); 5 s2.say(); 6 } 7 }