单例设计模式
保证类在内存中只有一个对象。
如何保证类在内存中只有一个对象呢?
- (1) 控制类的创建,只让本类来管理本类的对象的创建。private修饰构造方法。
- (2) 在本类中定义一个本类的对象。static Singleton s。
(3) 保证对象行为不影响自身的状态。两种策略:
- ① 采用“饿汉式”or“懒汉式”单例设计模式;
- ② 用final直接修饰属性
为什么说第三个条件是必要的呢?看如下的例子:
class Singleton {
//1.私有构造方法,其他类不能访问该构造方法。
private Singleton(){}
//2.声明一个引用
public static Singleton s = new Singleton();
}
- 如上的代码片段,已经满足了条件(1)和(2),为什么说其没有实现单例模式呢?观察如下的测试代码片段:
Singleton s1 = Singleton.s;
Singleton.s = null;
Singleton s2 = Singleton.s;
System.out.println(s1 == s2); // 结果为false
- 原因很简单:s1引用指向的是一个Singleton对象,而s2的引用指向的是null,所以比较引用,两者是不同的。不满足单例模式。
单例的3种写法:
- (1) 饿汉式(开发中使用,推荐)
class Singleton {
//1.私有构造方法,其他类不能访问该构造方法.
private Singleton(){}
//2.创建本类私有对象
private static Singleton s = new Singleton();
//3.对外提供公共的访问方法
public static Singleton getInstance() {
return s;
}
}
- (2) 懒汉式 (单例的延迟加载模式,有并发问题)
class Singleton {
//1.私有构造方法,其他类不能访问该构造方法.
private Singleton(){}
//2.声明一个私有引用
private static Singleton s ;
//3.对外提供公共的访问方法
public static Singleton getInstance() {
if(s == null) {
//此处存在并发问题
s = new Singleton();
}
return s;
}
}
- (3) final
class Singleton {
//1.私有构造方法,其他类不能访问该构造方法
private Singleton(){}
//2.声明一个引用
public static final Singleton s = new Singleton();
}
饿汉式和懒汉式的区别
区别 | 饿汉式 | 懒汉式 |
---|---|---|
时空 | 空间换时间 | 时间换空间 |
多线程访问 | 不会创建多个对象 | 有可能会创建多个对象 |
实际场景
- java.lang.Runtime 采用饿汉式的单例设计模式