美文网首页
单例模式

单例模式

作者: 神坛下的我 | 来源:发表于2018-10-20 15:00 被阅读0次

    单例模式

    • 单例模式的核心作用
      保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。
    • 常见应用场景
      Windows的任务管理器和回收站,读取配置文件的类一般也只有一个对象,网站的计数器,应用程序日志应用实现,数据库连接池的设计,操作系统的文件系统,Servlet中的Application,Spring中每个Bean默认是单例,Servlet编程中每个Servlet也是单例,SpringMVC和struts1中控制器对象也是单例。
    • 单例的优点
      当一个对象的产生需要比较多的资源时,可以通过在应用启动时直接产生一个单例对象,然后通过永久驻留内存的方式解决;可以在系统设置全局的访问点,优化共享资源访问,如负责所有数据表的映射处理。
    • 常见五种实现形式:
    1. 饿汉式(线程安全,调用效率高,不能延时加载)
    public class A{
     private static A a = new A();//类初始化时,立即加载这个对象
     private A(){}
     public static A getInstance(){return a;}
    }
    

    饿汉式单例中,static变量会在类装载时初始化,也不会涉及多个线程对象访问该对象的问题,虚拟机保证只会装载一次该类,不会发生并发访问问题。可以省略synchronized。但是如果只是加载本类,而不是要调用getInstance方法,会造成资源浪费!

    1. 懒汉式(线程安全,效率不高,可以延时加载
    public class A{
     private static A a;
     private A(){}
     public static synchronized A getInstance(){
      if(a==null){a = new A();}
      return a;
     }
     
    }
    

    lazyload:延时加载,懒加载,真正用的时候加载。每次调用getInstance方法都要同步,并发效率低。

    1. 双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题
      这个模块将同步内容放到了if内部,提高了执行效率,不必每次获取对象时都进行同步,只有第一次才同步。
    2. 静态内部模式(线程安全,效率高,可以延时加载
      静态内部类实现方式(也是一种懒加载方式):
    public class A{
    private static class AInstance{
    private static final A a = new A();
    }
    public static A getInstance(){return AInstance.a;}
    private A(){}
    }
    

    外部类没有static属性,不会立即加载对象。只有真正调用getInstance方法才会加载匿名内部类,兼备了并发高效调用和延时加载。

    1. 枚举单例(线程安全,效率高,不能延时加载
    public enum A{INSTANCE;//一个枚举元素,它就代表了Singleton的一个实例
    public void AOperation(){//功能处理}
    }//单例可以有自己的操作
    

    优点:实现简单,枚举本身就是单例模式(由JVM从根本上提供保障,避免反射和反序列化的漏洞)。
    缺点:无延时加载。


    • 单例模式存在的问题
    1. 防止反射:在构造方法中手动抛出异常控制
      private A(){if(a!=null){throw new RuntimeException();}}
    2. 防止反序列化:在单例类中建一个新方法
      private Object readResolve() throws ObjectStreamException{return a;}
      反序列化时,定义了此方法则直接返回此方法制定的对象,而不会单独创建新对象。
    • 多线程环境下效率由高到低:
      饿汉式 > 静态内部类式 > 枚举式 > 双重检查锁式 > 懒汉式
      选用:单例对象占用资源少,不需要延时加载:枚举式>饿汉式。
      单例对象占用资源大,需要延时加载:静态内部类式>懒汉式。

    相关文章

      网友评论

          本文标题:单例模式

          本文链接:https://www.haomeiwen.com/subject/sekmzftx.html