[首页]
[文章]
[教程]
首页
Web开发
Windows开发
编程语言
数据库技术
移动平台
系统服务
微信
设计
布布扣
其他
数据分析
首页
>
其他
> 详细
创建者模式之单例模式
时间:
2021-07-26 14:49:28
阅读:
17
评论:
0
收藏:
0
[点我收藏+]
单例模式
定义:
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象
我的理解:其实就是构造方法私有化,然后在本类中创建一个返回值为本类名的方法,用来使外部类调用此方法创建唯一的一个对象
特点:
单例类只能有一个实例。
单例类必须自己创建自己的唯一实例。
单例类必须给所有其他对象提供这一实例。
类型:
单例设计模式分类两种
1.
饿汉单例(类加载就会导致该单实例对象被创建)
优缺点:
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
实例
静态变量方式的单例模式
该方式在成员位置声明Singleton类型的静态变量,并创建Singleton类的对象instance。instance对象是随着类的加载而创建的。如果该对象足够大的话,而一直没有使用就会造成内存的浪费。
静态代码块方式的单例模式
该方式在成员位置声明Singleton类型的静态变量,而对象的创建是在静态代码块中,也是对着类的加载而创建。所以和饿汉式的方式1基本上一样,当然该方式也存在内存浪费问题。
2
.懒汉单例(类加载不会导致该单实例对象被创建,而是首次使用该对象时才会创建)
懒汉式-方式一
:线程不安全(不推荐使用)
实例代码:
缺点
:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
懒汉式-方式二
:线程安全(synchronized
)
实例代码:
优缺点:
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
从下面代码我们可以看出,其实就是在
初始化instance
的时候
才会出现线程安全问题
,一旦初始化完成就不存在了。
懒汉式-方式三
:双重检查锁(推荐使用添加了volatile关键字的双重检查锁)
实例代码:
再来讨论一下懒汉模式中加锁的问题,对于 getInstance() 方法来说,绝大部分的操作都是读操作,读操作是线程安全的,所以我们
没必让每个线程必须持有锁才能调用该方法,我们需要调整加锁的时机。由此也产生了一种新的实现模式:双重检查锁模式
有瑕疵的双重检查锁代码(不推荐使用)
双重检查锁模式是一种
非常好的单例实现模式,解决了
单例、性能、线程安全问题,上面的双重检测锁模式看上去完美无缺,其实是存在问题,在多线程的情况下,可能会出现空指针问题,出现问题的原因是
JVM在实例化对象的时候会进行优化和指令重排序操作。
解决方法:解决双重检查锁模式带来空指针异常的问题,只需要
使用 volatile 关键字, volatile 关键字可以
保证可见性和有序性。
完美的代码(强烈推荐)
添加 volatile 关键字之后的双重检查锁模式是一种比较好的单例实现模式,能够保证在多线程的情况下线程安全也不会有性能问题。
懒汉式-方式四
:静态内部类方式(强烈推荐使用)
静态内部类单例模式中实例由内部类创建,由于 JVM 在加载外部类的过程中, 是不会加载静态内部类的, 只有内部类的属性/方法被调用时才会被加载, 并初始化其静态属性。静态属性由于被 static 修饰,保证只被实例化一次,并且严格保证实例化顺序。
实例代码:
第一次加载Singleton类时不会去初始化INSTANCE,只有第一次调用getInstance,虚拟机加载SingletonHolder并初始化INSTANCE,这样不仅能确保线程安全,也能保证 Singleton 类的唯一性。
优点:静态内部类单例模式是一种
优秀的单例模式,是开源项目中比较常用的一种单例模式。在没有
加任何锁的情况下,
保证了多线程下的安全,并且没有任何性能影响和空间的浪费。
枚举方式(恶汉式,比饿汉还吃内存)(
不受序列化和反射的破坏)
枚举类
实现单例模式是极力推荐的单例实现模式,因为
枚举类型是线程安全的,并且
只会装载一次,设计者充分的使用了枚举的这个特性来实现单例模式,枚举的写法非常简单,而且
枚举类型是所有单例实现中唯一一种不会被破坏的单例实现模式。
实例代码
枚举方式属于恶汉式方式。
存在的问题
破坏单例模式:
使上面定义的单例类(Singleton)可以创建多个对象,
枚举方式除外。有两种方式破坏单例模式,分别是
序列化和
反射
。
序列化破坏单例
测试类
被破坏的单例类
序列化破坏单例的解决方法
在Singleton类中添加
readResolve()方法,在反序列化时被反射调用,如果定义了这个方法,就返回这个方法的值,如果没有定义,则返回新new出来的对象。
单例类的改进
源码解析:
ObjectInputStream类
反射破坏单例
测试类
被破坏的单例类
反射破坏单例的解决方法
单例类
测试类
JDK源码存在的单例模式
例如Rumtime.java
典型的饿汉型(静态变量)单例模式
例子(使用Runtime类中的方法)
以上内容整理于
幕布文档
,相关视频链接:https://www.bilibili.com/video/BV1Np4y1z7BU?p=22
创建者模式之单例模式
原文:https://www.cnblogs.com/gpjvm/p/15060804.html
踩
(
0
)
赞
(
0
)
举报
评论
一句话评论(
0
)
登录后才能评论!
分享档案
更多>
2021年09月23日 (328)
2021年09月24日 (313)
2021年09月17日 (191)
2021年09月15日 (369)
2021年09月16日 (411)
2021年09月13日 (439)
2021年09月11日 (398)
2021年09月12日 (393)
2021年09月10日 (160)
2021年09月08日 (222)
最新文章
更多>
2021/09/28 scripts
2022-05-27
vue自定义全局指令v-emoji限制input输入表情和特殊字符
2022-05-27
9.26学习总结
2022-05-27
vim操作
2022-05-27
深入理解计算机基础 第三章
2022-05-27
C++ string 作为形参与引用传递(转)
2022-05-27
python 加解密
2022-05-27
JavaScript-对象数组里根据id获取name,对象可能有children属性
2022-05-27
SQL语句——保持现有内容在后面增加内容
2022-05-27
virsh命令文档
2022-05-27
教程昨日排行
更多>
1.
list.reverse()
2.
Django Admin 管理工具
3.
AppML 案例模型
4.
HTML 标签列表(功能排序)
5.
HTML 颜色名
6.
HTML 语言代码
7.
jQuery 事件
8.
jEasyUI 创建分割按钮
9.
jEasyUI 创建复杂布局
10.
jEasyUI 创建简单窗口
友情链接
汇智网
PHP教程
插件网
关于我们
-
联系我们
-
留言反馈
- 联系我们:wmxa8@hotmail.com
© 2014
bubuko.com
版权所有
打开技术之扣,分享程序人生!