目录
1.饿汉式:
2.懒汉式
3.饿汉与懒汉哪一个是线程安全?
4.饿汉式与懒汉式的区别
5.单例模式的优点和缺点
6.单例模式的使用场景
目的:
使得类的一个对象成为该系统中的唯一实例
定义:
一个类有且仅有一实例,并且自行实例化(不能再类外实例化)向整个系统提供
要点:
1.某个类只有一个实例
2.必须自行创建实例
3.必须自行向整个系统提供这个实例
实现:
1.只提供一个私有的构造方法(可以使用默认的访问权限修饰符,但是必须是跨包去调用单例模式的类的时候)
2.含有的该类静态私有对象
3.提供一个静态的公有方法用于创建、获取静态私有对象
1.饿汉式:
特点:
创建对象的时候直接初始化,空间换时间,费空间,但是时间效率高。
饿汉式模式不管有没有调用对象,他都先去实例化对象
代码如下:
public class SingletonOne {
//将构造方法的访问控制权修饰符改为private,限制实例化只能再本类中进行
private SingletonOne() {
}
//创建有且唯一的实例
private static SingletonOne singletonOne = new SingletonOne();
//创建getInstance方法获取实例
public static SingletonOne getInstance() {
return singletonOne;
}
}
测试:
public class Text1 {
public static void main(String[] args) {
SingletonOne s1 = SingletonOne.getInstance();
SingletonOne s2 = SingletonOne.getInstance();
System.out.println(s1==s2);
}
}
因为在SingletonOne类中,构造方法是私有类型的,实例化的对象是私有的切唯一的,所以Text类中的s1等于s2。饿汉式在类加载的时候就创建好了对象,并且实例化了,浪费了空间,但是调用的时候,不用实例化,节省了时间
2.懒汉式
特点:
在创建对象的时候不去实例化,当第一次调用get方法时在实例化对象 时间换空间
代码如下:
public class SingletonTwo {
//创建私有的构造方法
private SingletonTwo() {
}
//创建本类有且唯一的对象,不初始化,当调用get方法时实例化
private static SingletonTwo sinletonTwo;
//创建共有的getInstanceof方法,初始化SingletonTwo对象,并对外提供实例的访问
public static SingletonTwo getInstance() {
if(sinletonTwo == null) {
sinletonTwo = new SingletonTwo();
}
return sinletonTwo;
}
}
测试:
public class Text1 {
public static void main(String[] args) {
SingletonTwo s1 = SingletonTwo.getInstance();
SingletonTwo s2 = SingletonTwo.getInstance();
System.out.println(s1==s2);
}
}
结果为:true
上述程序中,创建了一个内存,没有实例化(没有开辟空间),节省了空间,但是当你调用的时候,就要开辟空间,浪费了时间。
3.饿汉与懒汉哪一个是线程安全?
饿汉式线程安全。饿汉式在类加载的时候就已经拥有唯一的实例化了。getInstance方法在执行的时候需要时间,在懒汉模式中,假设第一次调用getInstance方法时,代码运行到了第六行(sinletonTwo = new SingletonTwo();),正在实例化(并没有跳出判断语句,此时的singletonTwo还是等于null),而这时候开始第二次调用getInstance方法,singletonTwo对象还会进入到if判断语句中,并再次实例化,违背了有且唯一性。所以懒汉式不是线程安全的。
4.饿汉式与懒汉式的区别
- 饿汉式在类加载的时候就创建实例,第一次加载速度快
- 懒汉式第一次使用时才进行实例化,第一次加载速度慢
- 饿汉式:空间换时间
- 懒汉式:时间换空间
5.单例模式的优点和缺点
优点:
- 在内存中只有一个对象,节省内存空间
- 避免频繁的创建销毁对象,提高性能
- 避免对共享资源的多重占用
缺点:
- 扩展比较困难
- 如果实例化后的对象长期不利用,系统会默认为垃圾进行回收,造成对象状态丢失



