设计模式——单例模式

单例模式


在当前进程中,通过单例模式创建的类有且只有一个实例。
特点:
1. 保证在一个JVM中,该对象只有一个实例存在
2. 构造器必须是私有的,外部类无法通过调用构造器方法创建该实例
3. 没有公开的set方法,外部类无法调用set方法创建该实例
4. 提供一个公开的get方法获取唯一的这个实例
优点:
1. 减少系统开销,减低内存使用频率
2. 避免对资源的重复占用

饿汉模式

把对象提前实例化,外部第一次获取这个类的对象时就直接存在这个类,省去创建的开销
//饿汉模式
class HungrySingleton{
    //1.私有构造函数,保证不能实例化本类
    private HungrySingleton(){}
    //2. 创建一个类的实例化对象
    private static HungrySingleton hungrySingleton = new HungrySingleton();
    //3. 创建一个get方法,返回一个实例
    public static HungrySingleton getInstance(){
        return hungrySingleton;
    }
}

懒汉模式

对象没有被提前实例化,外部第一次获取这个类的对象时是空的,需要初始化,赋值

线程不安全的模式

多个线程调用getInstance方法来获取Singleton的实例是,可能会导致实例化了两个对象
// 懒汉模式
class LazySingleton{
    //1.私有构造函数,保证不能实例化本类
    private LazySingleton(){}
    //2. 自己创建一个类的实例化 
    private  static LazySingleton singleton;
    //3. 创建一个get方法,返回实例
    public static LazySingleton getInstance(){
        //判断singleton是否为null,如果为null,即判定需要实例化
        if (singleton == null) {
            singleton= new LazySingleton();
        }
        return singleton;
    }
}

线程安全模式

// 懒汉模式
class LazySingleton{
    //1.私有构造函数,保证不能实例化本类
    private LazySingleton(){}
    //2. 自己创建一个类的实例化 (volatile保证不会发生重排序)
    private volatile static LazySingleton singleton;
    //3. 创建一个get方法,返回实例
    public static LazySingleton getInstance(){
        //判断singleton是否为null,如果为null,即判定需要实例化
        if (singleton == null) {
            //同步块,线程安全的创建实例
            synchronized (LazySingleton.class){
               // 再次检测实例是否存在
               if (singleton == null){
                   singleton= new LazySingleton();
                    // 字节码层
                    //JIT 即时编译 CPU
                    //1. 分配空间
                    //2. 初始化
                    //3. 引用赋值
                }
            }
        }
        return singleton;
    }
volatile的作用:
1. 防止指令重排序,对象的实例化包含创建和赋值
2. 保证内存可见,volatile修饰的变量,不会被本地缓存,所有线程对该对象的读写都会第一时间同步到主内存。

懒汉模式和饿汉模式的区别

两者的根本区别在于对象是否别提前实例化,以及线程的安全问题
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容