【Java_EE】设计模式

设计模式:解决一些固定场景的固定套路,是一种代码风格的知道指南。设计模式不止23种

1、单例设计模式

单例设计模式:确保一个类只有一个实例,提供全局访问点

单例模式的实现方式:

1:饿汉模式

java 复制代码
/**
 * 饿汉模式
 */
class SingletonPattern {
    private static SingletonPattern instance = new SingletonPattern();

    private SingletonPattern () {
        // 设置为private,外部类就不能通过new创建实例
    }

    public static SingletonPattern getInstance() {
        return instance;
    }
}

public class SinglePattern {
    public static void main(String[] args) {
        SingletonPattern instance1 = SingletonPattern.getInstance();
        SingletonPattern instance2 = SingletonPattern.getInstance();
        System.out.println(instance1 == instance2); // true
    }
}

2:懒汉模式

懒汉模式(线程不安全)

此处的代码是存在线程安全问题的。

1:原子性

应该将此处代码打包成原子的,不让代码穿插操作。所以就对代码进行加锁,解决原子性问题

if(instance == null) {

instance = new SingleLazy();

}

2:指令重排序

instance = new SingleLazy(); 此处这个new操作实际有好几步指令,粗略分为下面三步

1:内存分配

2:初始化零值

3:执行构造函数

实际的执行顺序是1-》2-》3,但是编译器优化的指令重排序,可能会将原本执行顺序重排为1-》3-》2,所以为了避免指令重排序,需要在instance上加上volatile

java 复制代码
class SingleLazy {
    /**
     * 单例模式
     * 懒汉模式:创建实例的时机比较晚,不是那么急迫
     */
    private static SingleLazy instance = null;

    private SingleLazy() {

    }

    // 第一次使用实例的时候,才创建实例
    public static SingleLazy getInstance() {
        if(instance == null) {
            // return new SingleLazy(); // 这样写是错的,这样每次get都会new
            instance = new SingleLazy();
        }
        return instance;
    } 
}
public class SingleLazyPattern {
    public static void main(String[] args) {
        SingleLazy instance1 = SingleLazy.getInstance();
        SingleLazy instance2 = SingleLazy.getInstance();
        System.out.println(instance1 == instance2); // true
    }
}

懒汉模式(线程安全)

又在锁的外面加了一条判断,目的就是只在第一次调用getInstance方法是进行加锁,避免重复加锁

if(instance == null)

// 如果不进行判断,那么每次调用getInstance方法都会进行加锁操作

// 但是如果加了判断,只会在第一次调用getInstance方法进行加锁操作

java 复制代码
class SinglePattern {

    private static volatile SinglePattern instance = null; // volatile解决指令重排序问题
    private static Object lock = new Object();

    private SinglePattern() {
        // 避免外部创建实例
    }

    public static SinglePattern getInstance() {
        if(instance == null) {
            // 如果不进行判断,那么每次调用getInstance方法都会进行加锁操作
            // 但是如果加了判断,只会在第一次调用getInstance方法进行加锁操作

            synchronized(lock) { // 加锁,解决原子性问题
                if(instance == null) {
                    instance = new SinglePattern();
                }
            }
        }
        return instance;
    }
}

public class SingleLazyPattern {
    
    public static void main(String[] args) {
        SinglePattern instance1 = SinglePattern.getInstance();
        SinglePattern instance2 = SinglePattern.getInstance();
        System.out.println(instance1 == instance2);
    }
    
}
相关推荐
爱吃牛肉的大老虎2 分钟前
Spring中用到的设计模式
java·spring·设计模式
Refrain_zc4 分钟前
Android TV 语音消息实战:遥控器 PCM 录音失真修复与扬声器强制播放方案
java
Stick_ZYZ5 分钟前
从“能调用工具”到“能稳定执行任务”:Agent 工程化的下一步
java·人工智能·后端·spring·ai
代码中介商8 分钟前
C++四大设计模式:单例、工厂、观察者、策略
java·c++·设计模式
宋志宗12 分钟前
从三层架构到清晰边界:一套更适合复杂 Java 服务的分层方法
java
iCxhust15 分钟前
c#多串口重量采集上位机程序
开发语言·汇编·c#·微机原理·8088单板机
lulu121654407822 分钟前
Codex Computer Use 深度分析:AI桌面自动化的技术突破与行业影响
java·运维·人工智能·自动化·ai编程
2401_8724187822 分钟前
什么是多范式编程语言?——以 C++ 为例深入理解编程范式
java·大数据·c++
一 乐23 分钟前
人口老龄化社区服务与管理平台|基于springboot+vue的人口老龄化社区服务与管理平台(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·人口老龄化社区服务与管理平台
東雪木26 分钟前
泛型、反射、注解(Spring 框架核心底层)专属复习笔记
java·windows·笔记·学习·spring