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

      单例模式的定义:确保一个类只有一个实例,并提供一个全局的访问点。

      在应用中,有些对象我们其实只需要一个,例如线程池之类的对象。如果这类对象产生过多不仅浪费资源还有可能引发其它异常。如果只需要达到只存在一个实例这个要求,我们只需要定义一个全局静态变量,然后约定大家都使用这个变量就可以了。的确也是这样的,但是如果有更好的办法能达到只有一个实例,并且带来更多的便利(如避免一开始就创建这个对象),我们是很乐意学习的。

      单例模式共分为三种:懒汉式单例、饿汉式单例、登记式单例。

    饿汉式单例

      它只有在第一次请求实例时才会去创建。类加载的时候不需要创建,并且第一次创建以后都不需要再创建。

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

      这种单例很简单,但有个缺点就是:无论这个类是否被使用都会创建这个实例。

    懒汉式单例

      这个懒汉式单例,算是对上述饿汉式单例的一个优化。它把对象的创建延迟至使用它的时候。

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

      但这种方式,在多线程下是不安全。比如当两个线程同时进入instance == null的判断,那么就会创建两个Singleton对象。要保证这个类的线程安全也很简单,只需要给getInstance方法加上同步锁就行了。

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

      但通常只有在第一次判断instance == null的时候才会出现不安全性,如果对整个方法加锁,则会产生很多不必要的开销。要避免这种开销,我们只需要在进入instance == null的时候才加锁。

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

    登记式单例

      上述饿汉式和懒汉式单例都把构造方法都私有了,它是不能被继承的。登记式单例就是为克服这一缺点而设计的。

      它会有一个实例池,如果没有会先创建并放到池中再返回实例,如果实例池中存在,则直接从池中取出来。

    public class Singleton {
    
       private static Map<String, Singleton> instance_pool = new HashMap<String, Singleton>();
       static {
          Singleton instance = new Singleton();
          instance_pool.put(Singleton.class.getName(), instance);
       }
    
       protected Singleton() {
       }
    
       public static Singleton getInstance(String name) {
          if (name == null)
             name = Singleton.class.getName();
          if (instance_pool.get(name) == null) {
             try {
                instance_pool.put(name, (Singleton) Class.forName(name).newInstance());
             } catch (InstantiationException e) {
                e.printStackTrace();
             } catch (IllegalAccessException e) {
                e.printStackTrace();
             } catch (ClassNotFoundException e) {
                e.printStackTrace();
             }
          }
          return instance_pool.get(name);
       }
    }

     

        

  • 相关阅读:
    shell script数组使用函数输出
    Yii2文件上传
    ubuntu 安装遇到黑屏
    使用函数
    ionCube 安装
    记录LNMP环境彻底删除绑定域名及网站文件夹/文件的过程
    lnmp环境 开启pathinfo
    国外知名设计教程网址收集
    26个国外在线教育网站
    前端学习网站汇总
  • 原文地址:https://www.cnblogs.com/zhangchaozheng/p/2583699.html
Copyright © 2011-2022 走看看