JAVA 设计模式(一) - 单例模式

JAVA 设计模式(一) - 单例模式

本篇文章主要讲下android 创建型设计模式中的单例模式.

单例模式保证一个类只有一个实例,并提供一个访问该实例的全局节点.

它的实现有多种实现方式:

1: 饿汉式

饿汉式:类加载时就创建实例 . 不支持延迟加载实例

java 复制代码
public class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() {
        return instance;
    }
}

2: 懒汉式

懒汉式: 使用时才创建实例. **支持延迟加载 **.缺点 : getInstance 使用了 synchronize 实现线程同步,导致这个方法的并发很低,每次调用都会频繁的枷锁、释放锁

java 复制代码
public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

3:双重校验锁

java 复制代码
public class Singleton {
    private volatile static Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

这里注意成员变量 instance使用了volatile 来修饰,作用就是禁止指令重排序.

指令重排是指在不改变程序执行结果的前提下,CPU为了提高程序执行效率,可能会对指令的执行顺序进行调整.

如上述代码,instance = new Singleton(); 实际执行了三步操作:

  1. 分配内存空间

  2. 初始化对象

  3. 将对象指向分配的内存空间

    如果不使用volatile 这个步骤就会出现1-3-2的顺序,从而导致其他线程获取到一个未初始化的对象.

volatile关键字可以确保变量的可见性和禁止指令重排。当一个变量被volatile修饰时,编译器和处理器会注意到这个变量是共享的,因此不会将该变量所在的代码块进行指令重排。这样就可以避免由于指令重排导致的线程安全问题。

4:内部类

java 复制代码
public class Singleton {
    private Singleton() {}
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

5:枚举

java 复制代码
public enum Singleton {
    INSTANCE;
}
相关推荐
邪修king11 小时前
Re:Linux 系统篇(三十五):进程间通信Chapter2:从匿名管道到进程池:Linux 进程间通信实战(深度理解「先描述,再组织」)
java·linux·运维
拆房老料11 小时前
【第四部分:Agentic 智能体设计模式】16. 一个 Prompt 搞不定复杂任务?试试 Prompt Chaining
java·前端·人工智能·设计模式·prompt
张张123y12 小时前
后端第十四课:Agent 记忆系统(让 Agent 记住上下文和用户,跨会话不健忘)
java·大数据·人工智能·python·agent·记忆
曹牧16 小时前
C#:空合并运算符
java·前端·数据库
布吉岛的石头17 小时前
Java 程序员第 50 阶段2:预训练的目标函数:自回归语言建模本质
java·开发语言·人工智能·深度学习·回归·transformer
golang学习记17 小时前
IDEA 2026年的玩法已经完全不同
java·ide·intellij-idea
紧跟先前的步伐17 小时前
Go AI Agent 实战 05|Temperature 与生成参数:让模型输出可控
java·人工智能·golang
金銀銅鐵17 小时前
[Java] 展示添加元素时 ArrayList 的内部变化
java·后端·ai编程
斌糖雪梨18 小时前
spring auth 核心流程详解
java·后端·spring
文丑颜不良啊19 小时前
LeetCode201~225题目解析
java·leetcode