| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 单例模式有这么多需要注意的 -> 正文阅读 |
|
[Java知识库]单例模式有这么多需要注意的 |
1、饿汉模式顾名思义就是很饿,对象不管有没有用到都在一开始就new出来放着,这样如果实例没有使用的话就会浪费内存,但是好处是,由于对象在一开始就创建好了,所以它具有天然的线程安全优势,由于没有加锁,性能也是非常优秀的。
测试:
饿汉模式没什么好说的,重点看看懒汉模式。 2、懒汉模式懒汉模式,顾名思义,非常懒,对象在用到的时候才创建,好处是解决了饿汉模式可能会浪费内存的缺点,在单线程模式下完美替代饿汉模式,但是既然是动态创建的,那就避免不了多线程环境下的并发异常,先不废话,看看简单的懒汉模式如何实现。 1.0版本
测试:
看起来没有任何问题,但是如果我们在多线程环境下测试呢?
修改测试类:
结果: 基本可以在13个线程开始执行之前完成实例的创建,所以后面都没有执行了,这个结果与你电脑性能有关,不同性能的电脑执行效果肯定是不一样的,但是都能得出这个结论:懒汉模式存在线程安全问题! 2.0 DCL双重检测锁模式通过加锁,解决基本的线程安全问题。
继续使用上面的测试:
我们试想一下,如果同时有多个线程同时获取实例,判断为空之后给实例分配内存空间,这样就会产生多个内存空间,最后只有一个实例获得了锁创建了实例,将实例放入自己分配的内存空间,其他的线程由于拿不到锁创建不了实例,将一个空的放入了内存空间,也就是直接跳过了第二个指令。本来应该1->2->3执行的指令,变成了1->3->2 这就是DCL中存在的指令重排现象,解决的办法即使在变量前面加一个
它的主要作用就是保证可见性,禁止指令重排。详细可以参看关于volatile。 所以最后我们的懒汉模式的代码为:
如果是面试,到这里就够了~ 如果想多了解一下,请往下看 天下没有不透风的墙,世上没有不出bug的代码,上面真的能确保只得到一个实例吗? 3.0 杜绝反射破环首先我们在之前的基础上进行测试,通过反射创建对象。
我们发现结果又为false了,也就是我们不能保证全局只有一个单例,这违反了单例模式的初衷。 既然是通过构造方法破坏了单例模式,那自然也是从构造方法改起,在原来代码中加入一个标志位,保证我们的构造方法只能调用一次不就好了吗?
测试代码不用改,再次测试! |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 13:02:31- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |