zoukankan      html  css  js  c++  java
  • 设计模式相关面试问题-单例

    单例的介绍:

    • 单例的概念:
      单例模式是一种对象创建模式,它用于产生一个对象的具体实例,它可以确保系统中一个类只产生一个实例。
    • 好处:
      1、对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销。
      2、由于new操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻GC压力,缩短GC停顿时间。

    单例的六种写法和各自特点:

    • 饿汉:
      代码:

      缺点:无法对instance实例做延时加载。
      优化:采用懒汉。
    • 懒汉:
      代码:

      但是!!它是线程不安全的,下面做实验:

      缺点:在多线程并发下这样的实现是无法保证实例是唯一的。
      优化:用懒汉线程安全方式。

    • 懒汉线程安全:
      它有两种方式,如下:


      缺点:性能
      优化:DCL

    • DCL(Double-checked Locking双重检查锁):

      但是!!代码还是存在问题,因为这块代码不是原子操作,如下:

      不是原子操作就意味着JVM针对标红的这句话会有如下处理:
      1、给instance分配内存。
      2、调用DCLSingleTon构造方法初始化初始化变量。
      3、将instance这个对象指向JVM分配的内存空间,
      但是!!!JVM有这样一个缺点:在既时编译器中,存在指令重排序的优化,也就是以上说的这三步操作不会按照咱们预期的顺序来执行,有可能第三步在第二步之前,也有可能第二步在第一步之前,这样就会造成线程不安全报错,解决方法如下:

      说到volatile关键字的作用可能都会想到可见性,也就是保证线程在本地不会存有instance的副本,而每次都会到内存中读取,事实上这种说法是不全面的,最主要使用它的原因就是禁止JVM指令的重排序优化。
      缺点:JVM的既时编译器中存在指令重排序的优化。
      优化:静态内部类 / 枚举

    • 静态内部类【推荐】
      为什么会有这种写法,其这是JVM提供的一种同步控制,什么意思?对于static和final关键字都是线程安全的,所以看一下具体写法:

      其中如果getInstance()方法木有调用其类也不会被加载,也就是既可以起到懒汉的效果,又能保证同步安全,而且木有使用synchronized关键字也不会影响性能,另外StaticInnerHolder是私有的也不能被外部所调用,简直完美!
      优点:JVM本身机制保证了线程安全 / 没有性能缺陷。

    • 枚举:
      具体写法如下:

      貌似也太简单了吧,但是!!对于里面的实例方法需要保证线程安全。
      安全:写法简单 / 线程安全【如果自己添加的实例方法和实例变量需要自己控制线程安全】。

    总结:

    • 饿汉:无法对instance实例进行延迟加载。
    • 懒汉:多线程并发情况下无法保证实例的唯一性。
    • 懒汉线程安全:使用synchronized导致性能缺陷。
    • DCL:JVM既时编译器的指令重排序。
    • 静态内部类 / 枚举:延迟加载 / 线程安全 / 性能优势。

    android中的单例:

    Application这个类就是典型单例的场景,也是在实际中大量使用的,如下:

  • 相关阅读:
    VS2015 C#利用QrCodeNet生成QR Code
    開玩樹莓派(二):配置IP,實現無顯示器局域網內Putty連接和RDP遠程
    開玩樹莓派(一):安裝Raspbian系統
    LINQ查询返回DataTable类型[轉]與将DataTable序列化为Json格式【轉】
    LINQ to Entities不支持Convert.ToDateTime方法解決一例
    ASP.Net MVC 控制@Html.DisplayFor日期显示格式
    jQuery在$(function(){})中調用函數
    ASP.NET MVC Identity 兩個多個連接字符串問題解決一例
    C#的WinForm中Label透明一例
    再centos7上添加新网卡eth1
  • 原文地址:https://www.cnblogs.com/webor2006/p/8990588.html
Copyright © 2011-2022 走看看