创建型模式-单例模式

一、定义

单例模式是一种创建型模式。

单例模式确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点。

1.1 单例模式的三个特点

  • 单例类的构造函数必须是私有的。单例类有且仅有一个实例,故不能让调用方使用new Class()来创建实例,要把类的初始化权限控制在类的内部。
  • 单例类通过一个私有的静态变量来存储唯一实例
  • 单例类通过提供一个公开的静态方法来供外部使用者可以访问到唯一实例。

1.2 单例模式的三个注意事项

  • 创建实例时,需要考虑是否线程安全
  • 实例的创建是否需要延迟加载
  • 获取实例时,是否要加锁

二、饿汉单例模式

饿汉单例模式在类加载时就立即进行初始化,创建单例对象。

  • 优点
    线程安全,实例化在线程出现之前,没有多线程同步问题。
    不需要加锁
  • 缺点
    没有用到的单例也会被创建,可能造成内存浪费

案例

public class HungrySingleton {
	private static final HungrySingleton singleton = new HungrySingleton();

	private HungrySingleton() {}

	public static HungrySingleton getInstance() {
		return singleton;
	}
}

三、懒汉单例模式

懒汉单例模式支持延迟加载,只有在第一次需要用到时才创建实例。不过也因此引入了线程安全问题,故在获取实例时需要加锁,这也导致性能降低。

  • 优点
    延迟加载,不造成内存浪费。
  • 缺点
    线程不安全,需要加锁
    因为加锁,影响并发性能

案例

public class LazySingleton {
    private static LazySingleton singleton;

    private LazySingleton() {}

    public synchronized static LazySingleton getInstance() {
        if (singleton == null) {
            System.out.println("=== 初始化 ===");
            singleton = new LazySingleton();
        }
        return singleton;
    }
}

案例:双重检查

其实只有在第一次创建实例时才需要加锁,之后的每次获取都是不需要加锁的,可以使用双重检查的方式进行优化。

  • 优点
    实例的创建时线程安全的。
    支持延迟加载。
    实例的获取无需加锁。
public class LazySingleton {
    private static volatile LazySingleton singleton = null;

    private LazySingleton() {}

    public static LazySingleton getInstance() {
        if (singleton == null) {
        	synchronized (LazySingleton.class) {
        		if (singleton == null) {
		            System.out.println("=== 初始化 ===");
		            singleton = new LazySingleton();
            	}
            }
        }
        return singleton;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值