zoukankan      html  css  js  c++  java
  • 单例模式

    • 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点
      • 在我们的系统中,有些对象其实只需要一个,比如说,线程池、缓存、对话框、注册表、日志对象、充当打印机、显卡等设备驱动程序的对象。
      • 这类对象只能有一个对象,制造多个可能会导致一些问题的产生:比如程序的行为异常、资源使用过量、或者不一致性的结果
    • 优点:
      • 对于频繁使用的对象,可以省略创建对象所花费的时间
      • 由于 new 操作的次数减少,对系统内存的使用频率也会降低,这将减轻 GC 压力,缩短 GC 停顿时间
    • 饿汉方式:全局的单例实例在类加载时构建
    • 懒汉方式:全局的单例模式在第一次被使用时构建
    • 饿汉方式
    public class Singleton {
           //在静态初始化器中创建单例实例,这段代码保证了线程安全
            private static Singleton uniqueInstance = new Singleton();
            //Singleton类只有一个构造方法并且是被private修饰的,所以用户无法通过new方法创建该对象实例
            private Singleton(){}
            public static Singleton getInstance(){
                return uniqueInstance;
            }
        }
      • JVM 在加载这个类时就创建了此唯一的单例实例,不会存在多个线程创建多个实例的情况,所以线程安全
      • 缺点:这个单例即便没有被使用也会被创建,在类加载之后就被创建,内存就浪费了
    • 懒汉方式(添加 synchronized)
    public class Singleton {  
          private static Singleton uniqueInstance;  
          private Singleton (){
          }   
          //没有加入synchronized关键字的版本是线程不安全的
          public static synchronized Singleton getInstance() {
              //判断当前单例是否已经存在,若存在则返回,不存在则再建立单例
              if (uniqueInstance == null) {  
                  uniqueInstance = new Singleton();  
              }  
              return uniqueInstance;  
          }  
     }
      • 在第一次被使用时创建,如果单例已经被创建了,再次调用接口将不会重新创建新的对象,而是直接返回之前创建的对象
      • 优点:如果某个单例使用的次数很少,并且创建单例消耗的资源较多,那么就需要实现单例的按需创建,使用懒汉模式是个不错的选择
      • 缺点:效率低,第一次加载需要实例化,反应稍慢
    • 双重检查单例(DCL实现单例)
    public class Singleton {
        //volatile保证,当uniqueInstance变量被初始化成Singleton实例时,多个线程可以正确处理uniqueInstance变量
        private volatile static Singleton uniqueInstance;
        private Singleton() {
        }
        public static Singleton getInstance() {
           //检查实例,如果不存在,就进入同步代码块
            if (uniqueInstance == null) {
                //只有第一次才彻底执行这里的代码
                synchronized(Singleton.class) {
                   //进入同步代码块后,再检查一次,如果仍是null,才创建实例
                    if (uniqueInstance == null) {
                        uniqueInstance = new Singleton();
                    }
                }
            }
            return uniqueInstance;
        }
    }
      • 利用双重检查加锁,首先检查实例是否已经创建,如果尚未创建,才进行同步。
      • 优点:资源利用率高,进行了双重的判断,第一层判断主要避免了不必要的同步
      • 缺点:第一次加载时稍慢。
    • 静态内部类实现单例
    public class Singleton {
    
        private Singleton() {
        }
    
        private static class SingletonHolder {
            private static final Singleton INSTANCE = new Singleton();
        }
    
        public static Singleton getUniqueInstance() {
            return SingletonHolder.INSTANCE;
        }
    }
      • 利用了类加载机制来保证只创建一个实例,与饿汉模式一样,也是利用了类加载机制,因此不存在多线程并发的问题
      • 不同的是,是在内部类里面去创建对象实例,这样的话,只要应用中不使用内部类,JVM 就不会去加载这个单例类,从而实现了懒汉方式的延迟加载
    • 枚举类实现单例
    public enum Singleton {
    
        INSTANCE;
    
        private String objName;
    
        public void doSomething() {}
    
    }
      • 相对于其他单例来说,写法最为简单,并且任何情况下都是单例的。jdk 1.5 之后才有的。
  • 相关阅读:
    setlocale set the current locale
    测试一个目录下的文件共有多少行
    ping中用到的校验和算法
    atomic integer operations P176
    我要理解1为什么是0xffffffff,所以写了下面的程序理解。
    贝叶斯网络中一个节点的类
    bash 的浮点除法
    shell(1)
    AndroidBroadcast详解与汇总
    AndroidActivity详解与汇总
  • 原文地址:https://www.cnblogs.com/BitingCat/p/10532582.html
Copyright © 2011-2022 走看看