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

    单例模式的含义

    单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例

    一般只有一个私有的构造方法,它可以通过调用公共的静态方法来获得这个实例

    单例模式的好处

    主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。

    使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收

    单例模式特点

    1、单例类只能有一个实例。

    2、单例类必须自己创建自己的唯一实例。

    3、单例类必须给所有其他对象提供这一实例。

    单例模式的选型:

     在实现层面上,目前的几种主要的单例模式往往有以下几项性能指标作为选型参考:

      -- 是否实现延迟加载

      -- 是否线程安全

      -- 并发访问性能

      -- 是否可以防止反射与反序列化穿透

    一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞。

    1.懒汉式单例

    在类加载的时候不创建单例实例。只有在第一次请求实例的时候的时候创建,并且只在第一次创建后,以后不再创建该类的实例。
    懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的

    //单例模式-懒汉式单例
    public class LazySingleton {
         //私有静态对象,加载时候不做初始化
         private static LazySingleton m_intance=null;
         // 私有构造方法,避免外部创建实例
         private LazySingleton(){}
         /**
          * 静态工厂方法,返回此类的唯一实例. 
          * 当发现实例没有初始化的时候,才初始化.
          */
         synchronized public static LazySingleton getInstance(){
             if(m_intance==null){
                 m_intance=new LazySingleton();
             }
             return m_intance;
         }
    }
    

     

    2. 饿汉式单例  

     在类加载的时候就创建实例,,在类创建的同时就已经创建好一个静态的对象供系统使用

    /*
    * 单例模式-饿汉式单例
    */
    public class EagerSingleton {
         /*
          * 私有的(private)唯一(static final)实例成员,在类加载的时候就创建好了单例对象
          */
         private static final EagerSingleton m_instance = new EagerSingleton();
    
         /**
          * 私有构造方法,避免外部创建实例
          */
         private EagerSingleton() {
         }
    
         /**
          * 静态工厂方法,返回此类的唯一实例.
          * @return EagerSingleton
          */
         public static EagerSingleton getInstance() {
             return m_instance;
         }
    }

    3. 登记式单例

    这个单例实际上维护的是一组单例类的实例,将这些实例存放在一个HashTable(登记薄)中,对于已经登记过的实例,则从工厂直接返回,对于没有登记的,则先登记,而后返回。 

    //用来存储单例(StringManager)的变量的hash类
    private static HashTable managers = new HashTable();
    //下面用关键字synchronized避免多线程时出错。
    public synchronized static StringManager getManager(String packageName){
        StringManager mgr = (StringManager)managers.get(packageName);
        if(mgr == null){
            mgr = new StringManager(packageName);
            managers.put(packageName,mgr);
       }
    return mgr;
    }
    

    4.双重锁定单例(改进懒汉式)

    考虑这样一种情况,就是有两个线程同时到达,即同时调用 getInstance() 方法。两个线程都会创建一个实例,这就违背了单例模式的初衷。因此加双重锁定

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

      

    啊啊

  • 相关阅读:
    git 获取领先落后的命令
    django orm 时间字段讲解
    在SAE上同步djanogo的mysql数据库
    使用JS来实现验证码功能
    一个基于python的即时通信程序
    关于python多线程编程中join()和setDaemon()的一点儿探究
    Django1.6添加comments应用的简单过程
    使用saltstack批量部署服务器运行环境事例——批量部署nagios客户端
    Web服务器集群搭建关键步骤纪要
    关于rsync的密码问题
  • 原文地址:https://www.cnblogs.com/kxdblog/p/8626076.html
Copyright © 2011-2022 走看看