单例设计模式


一、模式定义

单例模式保证了一个类只有一个实例,并提供一个全局访问点

二、使用场景

重量级对象,在创建时只需要创建一个即可,如数据库连接池,线程池。
比如我们在获取一个Connection时,我们不需要反复的去创建连接池,只要在开始的时候,创建一个连接池的单例对象,那么全局去使用这个对象去取Connection就可以了。

三、创建方法

1.懒汉式

懒汉式:延迟加载,在真正使用时才创建实例。
1)线程安全问题
2)加锁 并duoble check 进行优化
3)编译器(JIT)或者CPU可能对指令重排序,导致有线程使用到未初始化的实例。使用volatile关键字防止指令码重排序。

代码如下(示例):

public class LazySingleton {
	//volatitle防止指令码重排序,static 该属性属于类而不属于实例对象,所有实例对象共用一个类对象
    private volatile static LazySingleton instance; 
    //构造器私有,不允许其他位置创建实例
    private LazySingleton(){}                   
    //为什么要加synchronized关键字
    //在单线程情况下,同时创建实例,两个引用指向同一个实例
    //但是多线程情况下,两个线程同时创建实例,则引用指向不同实例,因此需要加上synchronized
    public static LazySingleton getInstance(){
        if(instance==null){
            synchronized (LazySingleton.class){
                if(instance==null){	//在判断一次,防止多个线程同时进入第一个判断后继续创建多个实例
                    instance=new LazySingleton();
                }
            }
        }
        return instance;
    }
}

2.饿汉式

饿汉式主要是基于JVM的类加载机制保证了线程安全

代码如下(示例):

public class HungrySingleton {
	//static+final 确定了该引用指向唯一的实例
    private static final HungrySingleton instance = new HungrySingleton();
    private HungrySingleton(){}
    public static HungrySingleton getInstance(){
        return instance;
    }
}

3.静态内部类

静态内部类:
1)本质上也是使用JVM的类加载机制保证线程安全
2)只有在调用getInstance()方法时,才会取初始化静态内部类,并完成该单例类的实例化(类似于懒汉式)

 代码如下(示例):
public class InnerClassSingleton {
    private static class InnerClassHolder{
        private static final InnerClassSingleton instance = new InnerClassSingleton();
    }
    private InnerClassSingleton(){}
    public static InnerClassSingleton getInstance(){
        return InnerClassHolder.instance;
    }
}

4.枚举Enum

Enum:
1)也是使用JVM的类加载器保证线程安全
2)类似于饿汉式
3)可以防止反射创建实例
4)可以防止反序列化对单例的破坏
代码如下(示例):

public enum EnumSingleton {
    INSTANCE;
}

四、对单例模式的破坏

1)反射方式创建实例
	这种方式破坏,饿汉式和静态内部类可以在构造器内进行判断来防止。
2)反序列化创建实例
	可以在单例类内写入readResolve()方法防止创建多个单例。也不能忘记设置序列化版本号。
static final long serialVersionUID = 42L;

Object readResolve() throws ObjectStreamException{
	return this.instance;
}
3)Enum类型天然防止了这两种破坏方式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值