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);
       }
    }

     

        

  • 相关阅读:
    JavaWeb之Ajax快速入门(十九)
    JavaWeb之文件上传与下载&邮件技术(十八)
    JavaWeb之Filter快速入门(十七)
    JavaWeb之JDBC分页/监听器(十六)
    JavaWeb之JDBC&自定义框架/DBUtil(十五)
    JavaWeb之JDBC(十四)
    JavaWeb之JDBC学习(十三)
    JavaWeb之Mysql代码练习(十二)
    [ 校内OJ ] NOIP2019模拟赛(五)
    【一本通】欧拉回路
  • 原文地址:https://www.cnblogs.com/zhangchaozheng/p/2583699.html
Copyright © 2011-2022 走看看