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

    1.什么是单例模式

    单例模式是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。
    理论上类的属性都是外部不可访问的,不然所有操作这个对象的都可以进行修改就违背了初衷。

    2.单例模式的几种实现

    2.1 饿汉式

    public class SingleObject {
        private String ob1;//属性不对外开放
          
       //创建 SingleObject 的一个对象
       private static SingleObject instance = new SingleObject();
     
       //让构造函数为 private,这样该类就不会被实例化
       private SingleObject(){}
     
       //获取唯一可用的对象
       public static SingleObject getInstance(){
          return instance;
       }
    

    饿汉式 是直接初始化了一个对象,不存在线程安全问题,但是类加载时就初始化,浪费内存。

    2.2 懒汉式(线程安全)

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

    在需要使用时,再初始化对象,如果已经初始化则直接返回该对象
    线程安全,不使用synchronized 关键字存在线程安全问题,多个线程同时getInstance 可能创建了多个对象。
    缺点:所有的操作都加了锁,性能较差

    2.3双重校验锁

    public class Singleton {  
        private volatile static Singleton singleton;  
        private Singleton (){}  
        public static Singleton getSingleton() {  
        if (singleton == null) {  
            synchronized (Singleton.class) {  
            if (singleton == null) {  
                singleton = new Singleton();  
            }  
            }  
        }  
        return singleton;  
        }  
    }
    

    这种方式采用双锁机制,安全且在多线程情况下能保持高性能。

    2.4 使用静态内部类

    public class Singleton {
        private static class SingletonInner {
            private static Singleton singleton = new Singleton();
        }
    
        private Singleton (){}
    
        public static Singleton getSingleton(){
            return SingletonInner.singleton;
        }
    }
    

    静态内部类初始化是在SingletonInner类初始化时触发的,并且由于静态内部类只会被加载一次,所以这种写法也是线程安全的。

    2.5 使用枚举实现单例

    上述各种实现都存在两个问题
    1.使用反射创建对象
    2.通过反序列化创建对象
    使用枚举实现单例可以天然的解决这两个问题
    参看:https://blog.csdn.net/javazejian/article/details/71333103

    3.单例模式的应用场景

    如果程序中的某个类对于所有客户端只有一个可用的实例, 可以使用单例模式。
    如果你需要更加严格地控制全局变量, 可以使用单例模式。

    1、要求生产唯一序列号。
    2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
    3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

  • 相关阅读:
    复用$.ajax方式传递参数错误处理
    JS传递函数并且调用
    JQuery $.axaj的基本格式
    AOP的具体实践-简化结果返回的处理
    将Python打包成可执行文件exe的心路历程
    通过Python实现一个文档的半自动录入工具
    我的第一次实习感悟
    docker nginx+php-fpm+mysql
    使用Harbor搭建docker私服
    python 验证码获取后处理降噪、灰度、保存
  • 原文地址:https://www.cnblogs.com/shinyrou/p/13689843.html
Copyright © 2011-2022 走看看