Java设计模式之单例模式

一、何谓单例模式?

单例模式,也叫单子模式,是一种常用的软件设计模式,属于创建型模式的一种。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。

实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。

单例模式在多线程的应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。

单例模式中比较常见的就是饿汉式懒汉式多线程下的双重检查锁式,以下分别进行Java代码实现:

二、单例模式代码实现

饿汉式

复制代码
/* 单例模式:饿汉式 */
public class EagerSingletonTest {
    private EagerSingletonTest() {} // 1. 私有化构造器,防止外部直接创建(暂且不考虑反射的影响)

    private final static EagerSingletonTest instance = new EagerSingletonTest(); // 2. 饿汉式,所以就得提前把对象创建好,并声明为final和static,因为“他”太饿了

    public static EagerSingletonTest getInstance(){ // 3. 定义获取单例实例的方法getInstance(),外界可以直接EagerSingletonTest.getInstance()来获取单例对象
        return instance;
    }
}
复制代码

懒汉式

复制代码
/* 单例模式:懒汉式 */
public class LazySingletonTest {
    private LazySingletonTest() {} // 1. 私有化构造器,防止外部直接创建(暂不考虑反射的影响)

    private static LazySingletonTest instance = null; // 2. 懒汉式,总是到deadline的时候才创建对象,因为“他”太懒了,所以初始化为null

    public static LazySingletonTest getInstance(){ //3. 定义获取单实例的方法getInstance(),外界可以直接调用,并获取单例对象
        if(instance == null){
            instance = new LazySingletonTest(); //4. 到了deadline了,才new一个对象供全局使用
        }
        return instance;
    }
}
复制代码

双重检查锁式

复制代码
/* 单例模式:双重检查锁(多线程懒汉增强式) */
public class DoubleCheckLockSingletonTest {
    private DoubleCheckLockSingletonTest() {}; // 第一步:私有化构造器,防止外部直接创建

    private static volatile DoubleCheckLockSingletonTest instance = null; // 第二步:利用懒汉式,并添加volatile防止指令重排

    public static DoubleCheckLockSingletonTest getInstance(){
        if(instance == null){ // 减少多线程时并发时后续线程的阻塞状况,提高性能
            synchronized(DoubleCheckLockSingletonTest.class){
                if(instance == null){ // 保证单例
                    instance = new DoubleCheckLockSingletonTest();
                }
            }
        }
        return instance;
    }
}
复制代码
posted @   RS_mine  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示