美文网首页
单例模式

单例模式

作者: 用户zzzzzz | 来源:发表于2022-08-27 21:18 被阅读0次
image.png image.png

单例模式常见写法

  • 构造方法私有
  • 提供全局的访问点
    1.饿汉式单例
    在单例类首次加载时就创建实例
    缺点:浪费内存空间
image.png
优化的写法,放在静态块( 在类初次被加载的时候执行且仅会被执行一次)
image.png

2.懒汉式单例
被外部类调用时才创建实例

  • 测试1

//懒汉式单例类.在第一次调用的时候实例化自己
public class Singleton1 {
    //1、第一步先将构造方法私有化
    private Singleton1() {}
    //2、然后声明一个静态变量保存单例的引用
    private static Singleton1 single = null;
    //3、通过提供一个静态方法来获得单例的引用
    //不安全的
    public static Singleton1 getInstance() {
        if (single == null) {
            single = new Singleton1();
        }
        return single;
    }
}
  • 测试2

//懒汉式单例.保证线程安全
public class Singleton2 {
    //1、第一步先将构造方法私有化
    private Singleton2() {}
    //2、然后声明一个静态变量保存单例的引用
    private static Singleton2 single=null;
    //3、通过提供一个静态方法来获得单例的引用
    //为了保证多线程环境下正确访问,给方法加上同步锁synchronized
    //慎用  synchronized 关键字,阻塞,性能非常低下的
    //加上synchronized关键字以后,对于getInstance()方法来说,它始终单线程来访问
    //没有充分利用上我们的计算机资源,造成资源的浪费
    public static synchronized Singleton2 getInstance() {
        if (single == null) {
            single = new Singleton2();
        }
        return single;  
    }
}
  • 测试3 (适中的方案)
//懒汉式单例.双重锁检查
public class Singleton3 {
    //1、第一步先将构造方法私有化
    private Singleton3() {}
    //2、然后声明一个静态变量保存单例的引用
    private static Singleton3 single=null;
    //3、通过提供一个静态方法来获得单例的引用
    //为了保证多线程环境下的另一种实现方式,双重锁检查
    //性能,第一次的时候
    public static Singleton3 getInstance() {  
      if (single == null) {
          synchronized (Singleton3.class) {
              if (single == null) {    
                  single = new Singleton3();
              }    
          }    
      }    
       return single;   
    }
}
image.png

第2步与第3步执行命令时顺序不一定哪个先执行,volatile可以解决这个问题

    private volatile static Singleton3 single=null;
  • 测试4 性能最优
//懒汉式(静态内部类)
//这种写法,即解决安全问题,又解决了性能问题
//这个代码,没有浪费一个字
public class Singleton4 {
    //1、先声明一个静态内部类
    //private 私有的保证别人不能修改
    //static 保证全局唯一
    private static class LazyHolder {
        //final 为了防止内部误操作,代理模式,GgLib的代理模式
        private static final Singleton4 INSTANCE = new Singleton4();
    }
    //2、将默认构造方法私有化
    private Singleton4 (){}
    //相当于有一个默认的public的无参的构造方法,就意味着在代码中随时都可以new出来
        
    //3、同样提供静态方法获取实例
    //final 确保别人不能覆盖
    public static final Singleton4 getInstance() {  
        
        //方法中的逻辑,是要在用户调用的时候才开始执行的
        //方法中实现逻辑需要分配内存,也是调用时才分配的
        return LazyHolder.INSTANCE;
    }
    
//  static int a = 1;
//  //不管该class有没有实例化,static静态块总会在classLoader执行完以后,就加载完毕
//  static{
//      //静态块中的内容,只能访问静态属性和静态方法
//      //只要是静态方法或者属性,直接可以用Class的名字就能点出来
//      Singleton4.a = 2;
//      //JVM 内存中的静态区,这一块的内容是公共的 
//  }
}

//我们所写的所有的代码,在java的反射机制面前,都是裸奔的
//反射机制是可以拿到private修饰的内容的
//我们可以理解成即使加上private也不靠谱(按正常套路出牌,貌似可以)


//类装载到JVM中过程
//1、从上往下(必须声明在前,使用在后)
//先属性、后方法
//先静态、后动态

3.注册式单例
将每一个实例都缓存到统一的容器中,使用唯一标识获取实例

  • 枚举式单例
public enum  Singleton7 {
    INSTANCE;

    private Object data;

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public static Singleton7 getInstance() {
        return INSTANCE;
    }

}
  • 容器式单例

4.ThreadLocal单例
保证线程内部的全局唯一,且天生线程安全

image.png

优点

image.png
缺点 image.png
总结 image.png

相关文章

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

  • 2018-04-08php实战设计模式

    一、单例模式 单例模式是最经典的设计模式之一,到底什么是单例?单例模式适用场景是什么?单例模式如何设计?php中单...

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

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

  • Telegram开源项目之单例模式

    NotificationCenter的单例模式 NotificationCenter的单例模式分析 这种单例模式是...

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • IOS单例模式的底层原理

    单例介绍 本文源码下载地址 1.什么是单例 说到单例首先要提到单例模式,因为单例模式是单例存在的目的 单例模式是一...

  • 单例

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

  • 单例模式

    单例模式1 单例模式2

  • java的单例模式

    饿汉单例模式 懒汉单例模式

网友评论

      本文标题:单例模式

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