设计模式-单例模式

目录

单例模式

懒汉式

饿汉式

双重锁模式

静态内部类模式

枚举模式

volatile关键字


单例模式

概念:顾名思义就是只有一个实例,并且它自己负责创建自己的对象,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象

特点:类构造器私有,持有自己类型的属性,对外提供获取实例的静态方法

懒汉式

特点:在需要获取实例对象的时候才去加载

问题:不是线程安全,同时两个线程进行获取实例对象时有可能获取到不同的对象

package com.anran.example.Singleton;

public class LazyMode {
    /**
     * 静态的自身对象
     */
    private static LazyMode lazyModes;

    /**
     * 私有构造方法
     */
    private LazyMode() {

    }

    /**
     * 唯一获取当前对象实例的静态方法
     * @return
     */
    public static LazyMode getInstance(){
        if (null == lazyModes) {
            lazyModes = new LazyMode();
        }
        return lazyModes;
    }
}

饿汉式

特点:在系统加载的时候就会对实例对象进行创建

问题:线程安全,但是浪费了内存空间

package com.anran.example.Singleton;

public class StarvingMode {
    private static StarvingMode starvingModes = new StarvingMode();

    private StarvingMode(){

    }

    public static StarvingMode getInstance(){
        return starvingModes;
    }
}

双重锁模式

描述:对实例对象进行加锁操作和原子操作,保证多线程在创建对象时阻塞

特点:做到了线程安全,延迟初始化,并且多线程并发时高效

volatile :保证创建对象时jvm的底层操作不会出现指令重新排序,从而保证第二个线程判断实例对象是否创建时的准确性

package com.anran.example.Singleton;

public class DoubleCheckModel {
    private static volatile DoubleCheckModel doubleCheckModel;

    private DoubleCheckModel(){

    }

    public DoubleCheckModel getInstance(){
        if (null == doubleCheckModel) {
            synchronized (DoubleCheckModel.class) {
                if (null == doubleCheckModel) {
                    doubleCheckModel = new DoubleCheckModel();
                }
            }
        }
        return  doubleCheckModel;
    }
}

静态内部类模式

描述:在获取 实例对象的时候,虚拟机才去加载静态内部类并初始化,此时只有一个线程可以获得对象的初始化锁,其他线程无法进行初始化,保证对象的唯一性

特点:线程安全,延迟加载

package com.anran.example.Singleton;

public class StaticClassMode {
    private StaticClassMode() {

    }

    public static StaticClassMode getInstance(){
        return Inner.staticClassMode;
    }

    private static class Inner{
        private static final StaticClassMode staticClassMode = new StaticClassMode();
    }
}

枚举模式

特点:枚举类隐藏了私有的构造器,枚举类的域 是相应类型的一个实例对象

package com.anran.example.Singleton;

public enum EnumMode {
    // 实例对象
    INSTANCE;

    // 可以补充其他操作

    // 获取实例对象
    public static EnumMode getInstance() {
        return EnumMode.INSTANCE;
    }
}

 

volatile关键字

保证对象创建在JVM中的执行过程中不会指令重新排序(原子操作)

JVM在创建对象的时候大致可以概括为(分配内存空间,初始化对象,外部引用指向内存空间),但在jvm实际执行的时候可能因为指令重新排序变成(分配内存空间,外部引用指向内存地址,初始化对象),此时可能导致对象没有创建完成就被后续程序使用,导致未知异常。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值