设计模式--单例模式

单例模式:意思是只有一个实例,这个类提供了一种获取其唯一的对象的方式,可以直接访问。以下是单例模式几种实现方式。
1,懒汉式

class Singleton1{
    //懒汉式
    //volatile 特性:有序性,禁止指令重排
    private static volatile Singleton1 instance;
    private Singleton1(){}
    public static Singleton1 getInstance(){
        if(instance == null){
            synchronized (Singleton1.class){
                if(instance == null){
                    instance = new Singleton1();
                }
            }
        }
        return instance;
    }
}

使用volatile 关键字 分析:
当new 一个对象时,大致要执行的字节码指令:
new:创建对象实例
dup:复制栈顶一个字长的数据,将复制的数据压栈
invokespecial:编译时方法绑定调用的方法。
astore_1:将栈顶引用类型值保存到局部变量。
分为三步:
a,分配空间
b,初始化
c, 引用赋值
正常执行顺序是a-b-c,JIT(即时编译),CPU可对b,c进行指令重排,单线程情况下不影响最后结果,多线程时则可能出现异常,当c先执行,此时instance 不为null,再来一个线程走到第一次null值判断就直接返回了,此时instance 还未初始化,后面可能会出现异常。
volatile 特性:有序性,禁止指令重排则可以解决上述问题。
2,饿汉式

class Singleton2{
    //饿汉式
    private static final Singleton2 instance = new Singleton2();
    private Singleton2(){}
    private static Singleton2 getInstance(){
        return instance;
    }
}

3,静态内部类 实现单例模式

class Singleton3{
    //静态内部类 实现单例模式
    static class Singleton4{
        private static final Singleton3 instance = new Singleton3();
    }
    private Singleton3(){}
    public static Singleton3 getInstance(){
        return Singleton4.instance;
    }
}

4,枚举实现单例

enum Singleton5{
    //枚举实现单例
    INSTANCE;
    public void test(){
        System.out.println("1111111");
    }
}

2,3,4 利用了类加载机制,jvm 来确保实体的唯一。
5,反射攻击:枚举类天然防止反射攻击,下为newInstance方法部分代码:

if ((clazz.getModifiers() & Modifier.ENUM) != 0)
            throw new IllegalArgumentException("Cannot reflectively create enum objects");
  其他的通过反射获取实体可以破坏单例模式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值