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

    单例模式

    核心作用 :

    • 保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。

    应用场景:

    1. 网站计数器
    2. 数据库连接池的设计
    3. Spring容器 等等

    模式优点:

    1. – 由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要
      比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动
      时直接产生一个单例对象,然后永久驻留内存的方式来解决
    2. – 单例模式可以在系统设置全局的访问点,优化环共享资源访问,例如可以设计
      一个单例类,负责所有数据表的映射处理

    常见实现:

    • 主要:

    1. 饿汉式

    描述: static变量会在类装载时初始化,由虚拟机保证单线程,可以省略synchronized关键字。

    优点: 线程安全,调用效率高。

    缺点: 不能延时加载;若只加载本类,而未调用getInstance(),则造成资源浪费!

    示例:

    public class SingletonHungry {
        private static SingletonHungry instance = new SingletonHungry();
        private SingletonHungry(){} // 私有化构造器
        public static SingletonHungry getInstance(){
            return instance;
        }
    }
    

    2. 懒汉式

    描述:

    优点: 线程安全,调用效率不高。 但是,有利于资源利用;可以延时加载。

    缺点:每次调用getInstance()方法同步,并发效率较低。

    示例:

    public class SingletonLazy {
        private static instance;
        private SingletonLazy(){} // 私有化构造器
        public static synchronized SingletonLazy getInstance(){
            if(instance == null){
                instace = new SingletonLzay();
            }
            return instance;
        }
    }
    
    • 其他

    3. 双重检测锁式

    描述: 将同步内容放到if内部,提高效率,仅第一次未创建时需要同步

    缺点: 由于JVM底层内部模型原因,偶尔会出问题。不建议使用

    示例:

    public class Singleton {
        private static Singleton instance = null;
    
        private Singleton() {
        }
    
        public static Singleton getInstance() {
            if (instance == null) {
                Singleton sc;
                synchronized (Singleton.class) {
                    sc = instance;
                    if (sc == null) {
                        synchronized (Singleton.class) {
                            if (sc == null) {
                                sc = new Singleton();
                            }
                        }
                        instance = sc;
                    }
                }
            }
            return instance;
        }
    }
    

    4. 静态内部类式

    描述: 外部类没有静态属性, 静态内部类只在被调用时才会加载。类加载是线程安全的。 同时static final保证了内存中唯一实例存在且只能被赋值一次,保证了线程安全性.

    优点: 线程安全,调用效率高,可以延时加载.

    缺点: (反射和反序列化可破解以上几种单例实现方式)

    示例:

    public class Singleton {
        private Singleton() {
    	}
    	private static class SingletonInnerClass {
    		private static final Singleton instance = new Singleton();
    	}
    	public static Singleton getInstance() {
    		return SingletonInnerClass.instance;
    	}
    }
    

    5. 枚举单例

    描述: 枚举本身就是单例模式。由JVM从根本上提供保障!避免通过反射和反序列化的漏洞!

    优点: 线程安全,实现简单.

    缺点: 不能延时加载.

    示例:

    public enum SingletonEnum{
    
    // 定义一个枚举的元素,代表SingletonEnum 的一个实例。
    INSTANCE;
    // 单例可以有自己的操作
    public void whateverMethod(){
    	// 功能处理
    	}
    }
    

    选择推荐:

    • 单例对象 占用 资源 少,不需要 延时加载:

    枚举式 好于 饿汉式

    • 单例对象 占用 资源 大,需要 延时加载:

    静态内部类式 好于 懒汉式

  • 相关阅读:
    【PowerOJ1754&网络流24题】负载平衡问题(费用流)
    【PowerOJ1753&网络流24题】分配问题(KM)
    【PowerOJ1752&网络流24题】运输问题(费用流)
    【PowerOJ1751&网络流24题】数字梯形问题(费用流)
    【PowerOJ1746&网络流24题】航空路线问题(费用流)
    【PowerOJ1744&网络流24题】方格取数问题(最小割)
    【PowerOJ1742&网络流24题】试题库问题(最大流)
    【PowerOJ1741&网络流24题】最长递增子序列问题(最大流)
    【PowerOJ1739&网络流24题】魔术球问题(最大流)
    邮件系统相关协议之SMTP
  • 原文地址:https://www.cnblogs.com/LingCoder/p/9972697.html
Copyright © 2011-2022 走看看