什么是单例模式?
在有些系统中,为了节省内存资源、保证数据的一致性,对某些类只能创建一个实例,这就是所谓的单例模式
应用场景?
保证JVM中只有一个单例模式
代码实现
-
方式一:恶汉式
public class Singleton { //方式一: 单例模式 private static Singleton singleton = new Singleton(); // 私有,只允许创建一次 private Singleton(){}; // 不允许别人创建 public static Singleton getInstance(){ return singleton; } }
优点:实现简单
缺点: 浪费内存(不管内存中是否含有对象实例,直接创建)
-
方式三:懒汉式
public class Singleton { private static Singleton singleton; // 私有,只允许创建一次 private Singleton(){}; // 不允许别人创建 public static Singleton getInstance(){ if(singleton == null){ // 优化 singleton = new Singleton(); } return singleton; } }
缺点:无法避免多线程创建对象并发问题
-
方式三:懒汉式+线程锁(加在方法上)
public class Singleton { private static Singleton singleton; // 私有,只允许创建一次 private Singleton(){}; // 不允许别人创建 public synchronized static Singleton getInstance(){ if(singleton == null){ // 优化 singleton = new Singleton(); } return singleton; } }
-
方法四:懒汉式+线程锁(加在具体执行代码上,只有执行到该代码才加锁)
public class Singleton { private static Singleton singleton; // 私有,只允许创建一次 private Singleton(){}; // 不允许别人创建 public static Singleton getInstance(){ if(singleton == null){ // 优化 synchronized (Singleton.class){ singleton = new Singleton(); } } return singleton; } }
优点:解决了上面创建性能的问题
缺点:JVM虚拟机,对象的开辟和赋值过程中,可能会产生指令重排序,防止指令重排序,在属性上加上修饰符 volatile
-
方法五:懒汉式+线程锁+volatile
public class Singleton { private static volatile Singleton singleton; // 私有,只允许创建一次 private Singleton(){}; // 不允许别人创建 public static Singleton getInstance(){ if(singleton == null){ // 优化 synchronized (Singleton.class){ singleton = new Singleton(); } } return singleton; } }
这样就完美了,但是用到的东西也比较多,所以 java中提供好了,如何实现单例模式的方法:使用 枚举
-
方法六:直接使用枚举
public enum Singleton { SINGLETON }