• 设计模式之【单例模式】


    完美的单例

    双重检查锁(DCL

    用处:延迟初始化,降低同步开销。double checked locking

    注意:single必须声明为volatile,且支持JDK1.5及以上版本。

    对象初始化需要三个步骤:

    memory=allocate();     //1.分配内存空间

    ctorInstance(memory)   //2.初始化对象

    instance=memory       //3.设置对象指向分配的内存

    如果single不是volatile的话,那么处理器会有可能重排序2 3步骤,导致多线程并发时得到实例已经分配内存空间,但并未初始化。

    Volatile保证了单例对象的原子性、可见性,禁止了步骤2 3的重排序。

    public class Singleton {
    
     
    
    private volatile static Singleton single;
    
    private Singleton(){
    
     
    
    }
    
     
    
    public static Singleton getInstance() {
    
    if(single==null){
    
    synchronized(Singleton.class){
    
    if(single==null){
    
    single=new Single();
    
    }
    
    }
    
    }
    
    return single;
    
    }
    
    }

    静态内部类单例

    好处:JVM在类的初始化阶段(即在Class被加载后,且被线程使用之前),会执行类的初始化。在执行类的初始化期间,JVM会去获取一个锁。这个锁可以同步多个线程对同一个类的初始化。

    基于类初始化锁【是类的初始化,并非对象初始化】的特性,可以以静态内部类的方式实现延迟初始化单例:

    public class Singleton {
    
    private static class SingletonHolder{
    
    public static Singleton single = new Singleton();
    
    }
    
     
    
    private Singleton(){
    
     
    
    }
    
     
    
    public static Singleton getInstance() {
    
    return SingletonHolder.single;
    
    }
    
    }

    初始化一个类,包括执行这个类的静态初始化和初始化这个类中声明的静态字段。根据JAVA规范,当发生如下情况,将初始化一个类:

    T是一个类,且T类的一个实例被创建;

    T是一个类,且T类中声明的一个静态方法被调用;

    T中声明的一个静态字段被赋值;

    T中声明的一个静态字段被使用,且这个字段不是一个常量字段;

    T是一个顶级类,而且一个断言语句嵌套在T内部被执行。

    枚举

    枚举是天生的单例。

  • 相关阅读:
    acwing 116. 飞行员兄弟
    leetcode 1041. 困于环中的机器人
    acwing 110 防晒
    acwing 167. 木棒
    AcWing 166. 数独
    solr4.7新建core
    solr4.7新建core
    Solr4.7从文件创建索引
    Solr4.7从文件创建索引
    Solr4.7从文件创建索引
  • 原文地址:https://www.cnblogs.com/Dhouse/p/7117494.html
Copyright © 2020-2023  润新知