单例设计模式
单例设计模式
简介
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
代码讲解
首先需要知道的是单例模式分为两种创建方式:
- 饿汉式
- 类加载不会导致该单实例对象被创建,而是首次使用该对象时才会创建。
- 懒汉式
- 类加载就会导致该单实例对象被创建。
饿汉式
首先需要知道的就是,饿汉式是线程安全的,缺点就是可能造成内存的浪费问题。
方式一(静态变量法)
代码讲解:
代码语言:javascript代码运行次数:0运行复制public class Singleton {
// 首先的第一步就是把构造方法定义为
// 私有变量
private Singleton(){};
// 在成员位置使用静态方法创建该类
private static Singleton instance = new Singleton();
// 对外提供静态方法获取该对象
public static Singleton getInstance() {
return instance;
}
}
代码分析:
该方法是把instance
对象定义为static
静态成员变量,该对象会随着类的加载而创建,这样会导致一个问题,如果该对象所占用的内存比较大的话,那么如果这个对象一直得不到使用,会造成内存的严重的浪费问题。
方式二(静态代码块方式)
代码讲解:
代码语言:javascript代码运行次数:0运行复制package springbootstudy;
public class Singleton {
// 首先的第一步就是把构造方法定义为
// 私有变量
private Singleton(){};
// 在成员位置使用静态方法创建该类
private static Singleton instance;
// 通过静态代码块的成员初始化表的形式 进行创建
static {
instance = new Singleton();
}
// 对外提供静态方法获取该对象
public static Singleton getInstance() {
return instance;
}
}
代码分析: 第二种方式相比于,第一种方式的区别在于,生成的方式不一样,是在静态代码块中生成的,但是产生的结果是一样的,就是对象随着类的加载而创建,也存在内存浪费问题。
懒汉式
方式一(线程不安全)
代码讲解:
代码语言:javascript代码运行次数:0运行复制public class Singleton {
// 首先的第一步就是把构造方法定义为
// 私有变量
private Singleton(){};
// 在成员位置使用静态方法创建该类
private static Singleton instance;
// 对外提供静态方法获取该对象
public static Singleton getInstance() {
// 这个单例还没有被创建 那么就创建一个
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
代码分析:
上面的这种方式在单线程的时候是没有问题的,但是当运用到多线程环境的时候,就会出现线程安全问题,多个空的instance
对象同时进行请求,那么就会出现线程安全问题。
方式二(线程安全,利用锁来实现)
代码讲解:
代码语言:javascript代码运行次数:0运行复制public class Singleton {
// 首先的第一步就是把构造方法定义为
// 私有变量
private Singleton(){};
// 在成员位置使用静态方法创建该类
private static Singleton instance;
// 对提供的静态方法获取该对象
// 通过上锁的方式来解决多线程不安全的问题
public static synchronized Singleton getInstance() {
// 这个单例还没有被创建 那么就创建一个
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
代码分析:
该方法虽然解决了线程安全问题,但是通过在getInstance()
方法上面加上synchronized
关键字,会大大降低该方法的执行效率,然后我们分析可知,线程安全问题,主要是会在初始化instance
的时候出现,当初始化完成之后,就不存在了,所以前辈们就提出了这种方案。
方式三(双重检查锁)
代码讲解:
代码语言:javascript代码运行次数:0运行复制public class Singleton {
// 首先的第一步就是把构造方法定义为
// 私有变量
private Singleton(){};
// 在成员位置使用静态方法创建该类
private static Singleton instance;
// 对提供的静态方法获取该对象
// 通过上锁的方式来解决多线程不安全的问题
public static Singleton getInstance() {
// 第一次判断 如果instance不为空 那么就直接返回实例
// 不进入抢锁阶段
if (instance == null){
synchronized (){
// 反之当进入抢锁阶段后 再判断一次
// 对象是否为空
// 通过这种双重检测的方式,大大提高了效率
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
代码分析:
该方法是一种非常好的单例模式,在性能与线程安全上都实现了很好的优化,但是还是存在着问题,比如在多线程的情况下,还是会出现空指针问题,该问题是JVM
本身的问题,JVM
在实例化对象的时候会进行优化与指令重排序操作,从而导致空指针问题。
想要解决这个问题,只需要private static Singleton instance;
,前面加上volatile
关键字即可。
也就是private static volatile Singleton instance;
#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
上一篇:常见索引失效的情况
推荐阅读
留言与评论(共有 16 条评论) |
本站网友 自动检测设置 | 4分钟前 发表 |
单例设计模式 单例设计模式简介单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一 | |
本站网友 baiduboke | 5分钟前 发表 |
但是还是存在着问题 | |
本站网友 爱久弥新 | 29分钟前 发表 |
只需要private static Singleton instance; | |
本站网友 青岛东大皮肤病医院 | 22分钟前 发表 |
原始发表:2025-01-20 | |
本站网友 小贩之歌 | 1分钟前 发表 |
该对象会随着类的加载而创建 | |
本站网友 草根博客 | 27分钟前 发表 |
方式二(静态代码块方式)代码讲解:代码语言:javascript代码运行次数:0运行复制package springbootstudy; public class Singleton { // 首先的第一步就是把构造方法定义为 // 私有变量 private Singleton(){}; // 在成员位置使用静态方法创建该类 private static Singleton instance; // 通过静态代码块的成员初始化表的形式 进行创建 static { instance = new Singleton(); } // 对外提供静态方法获取该对象 public static Singleton getInstance() { return instance; } }代码分析: 第二种方式相比于 | |
本站网友 55556 | 20分钟前 发表 |
同时确保只有单个对象被创建 | |
本站网友 公安网监 | 16分钟前 发表 |
饿汉式是线程安全的 | |
本站网友 吸吮乳尖 | 26分钟前 发表 |
方式一(静态变量法)代码讲解:代码语言:javascript代码运行次数:0运行复制public class Singleton { // 首先的第一步就是把构造方法定义为 // 私有变量 private Singleton(){}; // 在成员位置使用静态方法创建该类 private static Singleton instance = new Singleton(); // 对外提供静态方法获取该对象 public static Singleton getInstance() { return instance; } }代码分析: 该方法是把instance对象定义为static静态成员变量 | |
本站网友 什么播放器好 | 18分钟前 发表 |
懒汉式 类加载就会导致该单实例对象被创建 | |
本站网友 equ | 29分钟前 发表 |
代码讲解首先需要知道的是单例模式分为两种创建方式:饿汉式 类加载不会导致该单实例对象被创建 | |
本站网友 再贷款利率 | 22分钟前 发表 |
但是通过在getInstance()方法上面加上synchronized关键字 | |
本站网友 康泰克 | 30分钟前 发表 |
前面加上volatile关键字即可 | |
本站网友 灵敏度特异度 | 19分钟前 发表 |
只需要private static Singleton instance; | |
本站网友 薛神 | 18分钟前 发表 |
如有侵权请联系 cloudcommunity@tencent 删除前往查看对象多线程设计模式线程安全变量 |