单例模式概述
单例模式,在整个应用中单例类只能有一个实例,而且单例类负责创建此唯一实例。
单例模式又可分为饿汉式单例和懒汉式单例
饿汉式单例
饿汉式单例是指单例类在加载的时候实例已经创建好,不管此实例会不会使用都会创建。
代码示例如下
class Singleton { private static final Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return instance; } }
懒汉式单例
懒汉式单例在饿汉式单例的基础上做了修改,只有在想要获取实例时单例类才会被实例化。
代码实例如下
class Singleton { private static Singleton instance = null; private Singleton() { } public static Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; } }
多线程下的单例模式
上述两种单例模式实现很简单,在单线程下不会有什么问题,但是如果是在多线程的情况下有可能会出现问题。比如如下场景:有一个单例类S,线程A调用S的getInstance()创建实例,判断完instance为null但是此时由于cpu时间切片切换线程B开始执行,同样创建S类的实例调用getInstance()方法,此时判断instance依然为null线程B创建完成后切换到线程A执行,线程a 由于已经检测完所以直接创建instance实例。这种情形下S类就创建了两个实例
在懒汉式单例形式中做修改,将创建操作放入同步代码块
class Singleton { private static Singleton instance = null; private Singleton() { } public synchronized static Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; } }
由于同步方法的效率问题,上述方法并不是最好的实现。
双重检查加锁
1 class Singleton 2 { 3 private static Singleton instance = null; 4 5 private Singleton() 6 { 7 } 8 9 public static Singleton getInstance() 10 { 11 12 if (instance == null) 13 { 14 synchronized (Singleton.class) 15 { 16 if (instance == null) 17 instance = new Singleton(); 18 } 19 } 20 return instance; 21 } 22 }
这样利用同步代码块,在只有instance为null 也就是需要创建instance的时候才去做同步处理,如果instance已经存在只需要直接返回。这样既保证了多线程情形下的单例实现,同时相比于直接使用同步方法提高了效率。
时间: 2024-12-31 06:37:44