| |
|
开发:
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知识库]单例模式 |
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其(唯一)的对象的方式,可以直接访问,不需要实例化该类的对象(不需要每次new)。 温馨提示:
主要来解决一个全局使用的类频繁的创建和销毁,当你想控制实例数目,节约系统资源的时候。 判断系统是否有了这个单例,如果有则返回,没有则创建。在实现单例的共同特点就是构造函数是私有的。 个人不太恰当的理解(如果错了请指正):把普通模式和单例模式理解为一根火柴(普通)和一个打火机(单例)的区别,火柴的燃烧要燃尽自己为代价,而打火机可以持续的供给,重复的销毁和创建,如果类占用内存空间较大,耗时也长,如果频繁的创建会产生不必要的消耗的时候,我们就可以建一个单例类供我们使用就好了。 举例:一个班级只能有一个班主任,只有当这个班主任走了,才能有新的班主任过来。 一个电脑有两台打印机设备,在输出的时候就不能两台打印机同时打印一个文件。 优点:在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁(比如管理学院首页页面缓存)。 避免对资源的多重占用 缺点:没有接口,不能继承,与单一职责原则冲突,只关心内部逻辑,而不管外面怎么实例化。 注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。 单例模式又分为四种(也可以叫五种,枚举用的相对来说比较少)
接下来就来一个个介绍........ 单例模式创建要求:
饿汉式直接创建对象,不存在线程安全问题。比较容易实现,类似的思想的很多。 举例说明更加清晰:就好比女人最喜欢的双十一,你一下把你家里不管(需要)还是(不需要)的都买了,认为以后会用的到的也买了。这样就会导致占用内存了。 代码展示:也可以使用枚举式(最简洁)和?静态代码块饿汉式(适合复杂实例化)
懒汉式从上面我们可以了解到饿汉式早早的就把对象创建好了,在执行一些逻辑的时候不存在线程安全问题,但是懒汉式会延迟创建对象可能会导致线程安全问题 线程不安全的源码展示(适合单线程):
对于这种单线程没问题,但是如果如果两个或多个线程来同时访问instance如果都为null同时申请的时候会对系统数据造成错误 线程安全的源码展示(适合多线程):既然上面那种不能实现多线称,那要这个单例干嘛?所以既然不允许多个线程同时访问,我们就给他加个锁(synchronized)不就可以了。
但是这样有啥问题呢?就是我获取这个单例对象的时候,被上锁了,你气不气?我们就是在创建这个单例时候多线程可能出现点问题,咱么获取的时候不存在线程安全问题啊。。你为啥获取也要锁??? 就好比我们去食堂吃饭,吃饭是不是要一个一个的排队去打饭,但是不妨碍你看着里面的菜流口水《干饭人》 双检锁/双重校验锁:相对来说实现比较复杂,这种方式采用了双锁(volatile 轻量级锁)(synchronized 重量级锁)机制,安全且在多线程情况下能保持高性能。后面我们就顺便把这两种锁扩展了。 getInstance() 的性能对应用程序很关键。
对于上述存在的问题,我们只要双重判定就行了
或许有人会问了两个null,为什么要两个?
这样就相对完美了 登记式/静态内部类(适用于多线程):这种方式能达到双检锁方式一样的功效,但实现更简单。对静态域使用延迟初始化,应使用这种方式而不是双检锁方式。这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。利用了 classloader 机制来保证初始化 静态内部类是个好方式。主要是静态内部类和外部类不是一起加载的,并且你去调用它的时候他就会初始化,并且类加载是线程安全的,这个不需要考虑线程安全问题。当加载完之后你就可以直接拿啦。这样也能达到延迟加载的作用。
枚举:种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。
懒汉式和饿汉式的区别:这里举个例子加深一下印象:大家平时都玩过游戏和下过游戏吧,就拿下游戏来举例,拿(我的世界)来举例吧。饿汉式就是一次性把所有的模块全部下完,不管你后续玩不玩都下完了,这样子等待和成本太大,懒汉式就是你要玩什么模块就下什么模块,避免过多的消耗。 volatile和synchronized的区别:看完上面是不是对这两个锁有了一些的认识,接下来我们就来扩展一下他们的区别。 首先需要理解线程安全的两个方面:
区别在于:
如果哪里写的不对的地方,还望指教,感谢支持。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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 19:12:48- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |