美文网首页Java设计模式
java 单例模式详解 百度云

java 单例模式详解 百度云

作者: 你看了的地方 | 来源:发表于2020-05-02 17:46 被阅读0次

CSDN地址:https://blog.csdn.net/weixin_45388036/article/details/105891362

引言: 学习笔记记录开始啦,接下来我会分享最常见的设计模式。今天开始第一篇:单例模式

微云学习地址:https://share.weiyun.com/50XCTqT

网盘学习地址:https://pan.baidu.com/s/1DHGGkMBmg7wmz6RBvLshLQ 提取码:y8t3

一:概念及理解

单例模式(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点。单例模式是创建型模式。

常见单例举例:ServletContext、ServletContextConfig ;在 Spring 框架应用中 ApplicationContext;数据库的连接池DBPool也都是单例形式。

优点:在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。避免对资源的多重占用。

缺点:没有接口,不能继承,要修改只能修改代码

单例共有特征:

        构造方法私有化(保证对象只能自己来创建)

        自己在内部创建自己的实例

        提供一个全局的访问点(一般是static方法)是拿到单例的入口

二、单例分类及详解

1、饿汉式单例

在单例类首次加载时就立即初始化,并且创建单例对象。不管有没有使用,先创建了再说。

第二种饿汉式单例写法:利用static方法块,在类加载时就构建了唯一对象;

优点:没有加任何的锁、执行效率比较高,在用户体验上来说,比懒汉式更好。

缺点:类加载的时候就初始化,不管用与不用都占着空间,浪费内存空间,如果从来没有使用也都创建了,小范围内影响不大,但是大范围使用不建议使用。

为了改善内存浪费,我们可以在使用到单例实例时再创建,这就时下面的懒汉式单例

2、懒汉式单例

特点:当用户要使用单例时才创建对象。(线程不安全)

以上懒汉式单例的实现是线程不安全的,并发环境下很可能出现多个Singleton实例,不同线程进入到if判断语句当中时,会出现创建多个不同实例的情况,偏离单例设计模式的初衷。

改进方法:通过synchronized来解决。

第一种:在getInstance方法上加同步synchronized(线程安全)

缺点:在getInstance方法上用synchronized 加锁,在线程数量比较多情况下,如果 CPU 分配压力上升,会导致大批量线程出现阻塞,从而导致程序运行性能大幅下降。于是下面第二种是更好的方式,既兼顾线程安全又提升程序性能

第二种:双重检查锁的单例模式,在getSingleton方法中对singleton进行两次判空。(线程安全)

更优方案:synchronized 关键字,总归是要上锁,对程序性能还是存在一定影响的。以下采用静态内部类的方式:

第三种:静态内部类方式(内部类先于外部类加载,调用getInstance方法时,内部类逻辑才会执行。性能最优的写法)(线程安全)

高级内容:(这里只做大概说明,具体可参考我头部链接一起学习)

1、反射破坏单例

我们前面所介绍的,单例模式必须满足构造方法私有化,避免外部实例化,而Java反射机制是能够实例化构造方法为private的类的,使所有的Java单例实现失效。

解决办法:在构造函数中抛出异常,提醒开发人员,不允许用反射机制创建单例。

2、序列化破坏单例

      当我们将一个单例对象创建好,序列化然后写入到磁盘,下次使用时再从磁盘中读取到对象,反序列化转化为内存对象。反序列化后的对象会重新分配内存,即重新创建。那如果序列化的目标的对象为单例对象,就违背了单例模式的初衷,相当于破坏了单例。

解决办法:在单例类中加上以下方法,覆盖了序列化对象,反序列化出来的对象,还是创建了两次,发生在JVM层次,之前反序列化出来的对象被GC回收。

3、注册式单例

解决了序列化问题,最安全单例;

每一个实例都登记到某一个地方,使用唯一的标识获取实例,一种为容器缓存,一种为枚举登记,下面介绍其中一种;

4、ThreadLocal单例

ThreadLocal 不能保证其创建的对象是全局唯一,但是能保证在单个线程中是唯一的,天生的线程安全。

单例模式小结:

单例模式可以保证内存里只有一个实例,减少了内存开销;可以避免对资源的多重占用。

单例模式关键点:

    构造函数方法为Private修饰。

    通过一个静态方法或者枚举返回单例类对象。

    需要确保单例类的对象有且只有一个,尤其是在多线程环境下。

    确保单例类对象在反序列化时不会重新构建对象。

重点掌握饿汉式与懒汉式两种单例模型。

饿汉式:不用也加载。线程安全的,可以直接用于多线程而不会出现问题,但会出现内存浪费情况,不推荐大范围使用

懒汉式:用时再加载。非线程安全,可通过getInstance方法上加同步synchronized、双重检查锁、静态内部类三种方式改善;

其中第一种每次都同步,性能不好,第二种两次非空检查,避免每次同步的性能损耗,第三种没有性能损耗。

相关文章

  • 单例模式安全之反射攻击

    单例模式安全之反射攻击 源码 单例模式这里就不谈了,什么是单例模式可参考七种Java单例模式详解,这里是关于单例模...

  • Java架构师课程

    Java架构班开学典礼 Spring中常用的设计模式概述及工厂模式详解 单例模式及原型模式单例模式及原型模式单例模...

  • 单例

    iOS单例模式iOS之单例模式初探iOS单例详解

  • java 单例模式详解 百度云

    CSDN地址:https://blog.csdn.net/weixin_45388036/article/deta...

  • 设计模式之单例模式详解

    设计模式之单例模式详解 单例模式写法大全,也许有你不知道的写法 导航 引言 什么是单例? 单例模式作用 单例模式的...

  • iOS 单例模式

    关于单例模式的详解,看完这几篇,就完全了然了。iOS 单例模式iOS中的单例模式iOS单例的写法

  • 单例模式

    单例模式及C++实现代码单例模式4种实现详解 c++11改进我们的模式之改进单例模式 单例模式(Singleton...

  • Java中单例模式你用的哪一种?

    一起讨论java中的单例模式。单例模式是java设计模式中算是最简单的设计模式了。 * java实现单例模式的写法...

  • JAVA设计模式 - 单例模式

    JAVA设计模式 - 单例模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一...

  • Java四种单例设计模式

    Java中的四种单例模式 单例模式是最容易理解的设计模式之一,介绍Java中单例模式的四种写法。 1.基本单例模式...

网友评论

    本文标题:java 单例模式详解 百度云

    本文链接:https://www.haomeiwen.com/subject/siakghtx.html