常用设计模式-单例模式(Singleton pattern)
一、单例模式目的
使用单例模式第一步要了解其作用,单例理解为一个实例(one instance)。保证一个类只有一个它的实例。在实际开发中,如线程池,数据库连接对象等。
二、实现思路
为了保证 one class one instance
①则需要保证实例全局唯一,保证实例全局唯一的方式这里选用的是可以使用 static 关键字修饰实例引用,静态字段全局共享,但是需要保证该实例引用自始至终只引用一个实例。实例可以在 bean 创建时创建(饥饿模式),也可以在需要时才实例化(减轻服务器压力,懒惰模式)。
②并且构造函数只能私有化,避免任何线程都能 new 一个实例
③其次开放一个访问入口,即属于类的 get 静态方法,用 static 修饰。
④获取实例时需要先判断实例已经创建才获取,未创建需要创建唯一的实例,下面为双重验证 + volatile方式创建实例的实现
双重验证 + volatile
public Class Singleton(){
private volatile static Singleton uniqueInstance;
private Singleton() {
}
public static Singleton getUniqueInstance() {
//先判断对象是否已经实例过,没有实例化过才进入加锁代码
if (uniqueInstance == null) {
//类对象加锁
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
如果单使用双重验证,由于已获得锁的线程在创建实例时,线程分三步执行指令(分配内存空间地址,初始化实例,引用指向内存空间地址),三步操作并非按排序进行,有可能先执行了第 3 步再执行第 2 步,另一线程在第一次验证时判断到实例引用不为空,即返回,线程对该实例引用的后续使用会造成空指针异常 。因此需要使用 volatile 保证指令不被重排序
但如果单使用 volatile,则不能保证线程实例化时这个操作的原子性。因此双重验证 + volatile便是处于这样的考虑。
标签:Singleton,pattern,uniqueInstance,实例,线程,单例,volatile,设计模式 From: https://www.cnblogs.com/zyiyiblog/p/18327118