【设计模式】单例模式

本文详细介绍了Java中三种常见的单例模式实现方式:线程安全的懒汉式、饿汉式以及双检锁/双重校验锁。懒汉式在多线程环境下可能出现线程安全问题,通过`synchronized`关键字解决;饿汉式则在类加载时就完成了初始化,确保线程安全;而双检锁在保证线程安全的同时,通过`volatile`关键字减少同步开销,提高效率。
摘要由CSDN通过智能技术生成

一、什么是 单例模式

从字面意思上来说,单例模式就是 只存在一个实例 的模式。只存在一个实例的好处是 内存中只存在一个实例,减少了内存的开销,避免了对象的频繁的创建于销毁。可以帮助我们控制实例的数目,节约系统资源。

二、常用的三种单例模式

第一种:线程安全-懒汉式

所谓的懒汉式,从字面意思上而言是一种慵懒的方式(被动)创建实例,即当你需要的时候且没有所需要是实例时,系统才去创建实例。
在这里插入图片描述

因为用被动的方式创建实例,在创建实例的过程中存在线程安全的问题,这里所说的线程安全问题是指存在多个实例被创建的情况,所以我们需要用的 synchronized 关键字保证线程安全。

// 实例
public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
    public static synchronized Singleton getInstance() {  
        // 此处存在线程安全,当多个线程同时调用此方法时,可能存在
        // 当 if 没有执行完,下一个线程右接着执行,造成多次实例化
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}

第二种:线程安全-饿汉式

所谓的饿汉式,从字面意思上而言是一种主动的创建方式,即一开始就已经进行了实例化,当多个线程进行调用时,饿汉式不存在对象没有被实例化的情况,即在线程调用的过程中不存在实例化的过程,这也就意味着并不会存在线程安全的问题。
在这里插入图片描述

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    // 线程在每次调用的时候,直接获取已经实例化之后的对象,不会存在线程安全的问题。
    public static Singleton getInstance() {  
    return instance;  
    }  
}

第三种:双检锁/双重校验锁

所谓的 双重校验锁 指的是具有两重检验:因为会有两次检查 instance == null,一次是在同步块外,一次是在同步块内。为什么在同步块内还要再检验一次?因为我们并没有在 getSingleton() 方法上使用 synchronized 关键字进行加锁,所以可能会有多个线程一起进入同步块外的 if,如果在同步块内不进行二次检验的话就会生成多个实例。

在这里插入图片描述

使用 volatile 关键字保证当由 volatile 关键字修饰的变量发生变化后,使用这个变量的线程会第一时间获取最新的值。从而保证了一致性。

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    // 因为没有在这个方法上加锁(synchronized),所以存在多个线程同时进入这个 if 的可能。
    if (singleton == null) {  
    	// 多个线程会依次执行此同步代码块。
        synchronized (Singleton.class) {  
            // 倘若不在此 if 进行判断,那么同时进行上层 if 的线程会在依次执行同步代码块
            // 的同时都会都会一个实例。
            if (singleton == null) {  
                singleton = new Singleton();  
            }  
        }  
    }  
    return singleton;  
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值