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;
}
相关推荐
古法安卓4 小时前
Android-日志系统源码解析
android·java·android studio
小夏coding5 小时前
从"一把梭"到"精妙拆解" —— 滑动窗口计时框架的设计演进
java·后端
MacroZheng6 小时前
同事问我:"Claude Code经常失忆,不怕它把项目搞炸?",我:"怕,三个Markdown文件给它装个永不丢失的外置大脑!"
java·人工智能·后端
十年Java程序媛8 小时前
深度实战:JDK21 虚拟线程 + HikariCP 生产正确配比、坑点、监控全套
java·spring boot
xiaoqiMikko8 小时前
有人在搜一个不存在的 Tomcat 版本
java·tomcat
学习星球8 小时前
AI Agent 成本工程实战:从 OpenAI Codex 的 8 个“烧 Token“Bug 学起
人工智能·设计模式·微信小程序
用户31268748772011 小时前
ConcurrentHashMap 怎么保证线程安全?从分段锁到 CAS+synchronized
java
vipxieliang11 小时前
ValidX vs Apache Commons Validator:功能与性能对比
java·spring boot
SimonKing11 小时前
升级Spring Boot 4后,从 Jackson 2 到 3,到底有哪些变化
java·后端·程序员
吃饱了得干活12 小时前
一篇讲清楚Spring Boot:自动装配、启动器、过滤器、拦截器、设计模式
java·spring boot·后端