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

    一.核心作用

     
            保证一个类只有一个实例,并且提供一个访问该实例的全局访问点
     
            整个程序只需要一个实例的场景。比如任务管理器,回收站,连接池,线程池。
     

    二.优点

     
            --由于单例模式只生成一个实例,减少系统性能的开销.当一个对象产生需要较多的资源时,可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存来解决.
            --单例模式可以在系统设置全局的访问点,优化资源访问.
     

    三.常见实现方式

     
            主要:
                    饿汉式    (线程安全    调用效率高       不能延时加载)
                    汉式    (线程安全    调用效率不高    能延时加载)
     
            其他:
                    双重检测锁式    将懒汉式的同步方法改为同步块
                    静态内部类式    (线程安全    调用效率高        能延时加载)
                    枚举单例           (线程安全    调用效率高        不能延时加载      可以防止反射和反序列化漏洞)
     

    四.如何选用

     
                    占用资源少,不需要延时加载
                    枚举式   好于    饿汉式
     
                    占用资源多,需要延时加载时
                    静态内部类      好于    懒汉式
     

    五.防止反射漏洞

     
                    在构造方法中加一个判断,若对象不等于null,则抛出异常 
     

    六.防止反序列化漏洞

     
                    在该类中添加readResolve(){    return Instance;    }
     
    package com.skd.designMode.simple;
    /*
    * 全局获取的实例是唯一的
    * 1.构造方法私有化
    * 2.对外提供静态方法(getInstance)来创建对象
    */
    public class Person
    {
        private static Person person;
    
        // 私有化构造方法
         
    
        private Person()
      {
        // 防止反射调用
        if (null != person)
        {
          throw new Exception();
        }
      }
    
        // 懒汉式
        // 延迟加载,方法需要同步,调用效率低
        public static synchronized Person getInstance()
        {
            if (person == null)
            {
                person = new Person();
            }
            return person;
        }         
    
        // 双重检测锁式
       // 此处将 person 声明为 volatile 即可得到唯一正确的 person 对象 public static Person getInstance2() { // 而且此处可能获得一个创建不完整的对象并返回
    // 初始化一个对象的时候,会经历内存分配、初始化、返回对象在堆上的引用等一系列操作,这种方式产生的对象是一个完整的对象,可以正常使用。虚拟机可能会进行指令重排序 if (null == person) { synchronized (Person.class) { // 此处不判断可能创建多个对象,因为第一次判空未加锁 if (null == person) { person = new Person(); } } } return person; } // 防止反序列化 public static Person readResolve() {   return person; } } // 饿汉式 class People { // 类初始化时立即加载该对象,虚拟机的同步机制保证其线程安全! // 无法延时加载 private static People people = new People(); // 私有化构造方法 private People() { } // 方法不需要同步,调用效率高 public static People getInstance() { return people; } } // 静态内部类式 // 这种方式线程安全,调用效率高,延时加载 class Teacher { // 私有化构造方法 private Teacher(){} // 静态内部类 private static class Inner { // 类初始化时立即加载该对象,虚拟机的同步机制保证其线程安全! static final Teacher teacher = new Teacher(); } // 返回静态内部类的静态属性teacher public static Teacher getInstance() { return Inner.teacher; } } // 枚举式 package com.skd.simple; public enum Simple { // 枚举本身也是一种单例 // 线程安全,效率高,无法延时加载 INSTANCE(new Object()); Object obj; HAHA(Object object) { obj = object; } }
     
     
     
     
     
     
     
    如果文章对您有所帮助,可以点一下推荐哦
  • 相关阅读:
    运放之典型应用
    关于set_clock_uncertainty的两点注意事项
    ARINC 429 接口简介
    关于set_input/output_delay中的clock_fall和add_delay选项
    卡诺图
    关于乒乓操作的一些小技巧
    程序Title样本参考
    【游戏】精忠报国岳飞传之基本说明一
    运放虚短虚断的简单推导
    我的小型网站搜索分词中遇到的问题
  • 原文地址:https://www.cnblogs.com/virgosnail/p/9445696.html
Copyright © 2011-2022 走看看