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

      单例模式是指确保在任何情况下,一个类只有一个实例,并提供一个全局的访问点。这样减少了内存开销,也避免了对资源的多重占用。单例模式看起来简单,实现起来也很简单。缺点是没有接口,扩展困难,若要扩展单例对象,只能修改代码,没有其他途径。

      一、饿汉式单例:加载类时创建类对象,绝对线程安全,在线程还未出现以前就实例化了,不存在线程安全问题。

        优点:没有任何锁,执行效率高,从用户体验上来说,比懒汉式好。

        缺点:类加载时就初始化,不管用与不用,都占着内存空间,浪费了内存,当实例多时,就严重浪费内存。

      二、懒汉式单例:被外部类调用时内部类才加载。有线程安全问题存在。

        解决线程安全方式:

          1:访问点方法加sycronize关键字,但当线程数量比较多时,CPU分配压力上升,会导致大批线程阻塞,从而使程序性能大幅下降。

          2:双重检查锁,在访问点内部加sycronize关键字,可能导致方法内部阻塞,程序性能优于第一种方法。

          3:使用静态内部类,在内部类里面初始化实例,利用了调用方法前先实例化内部类的特性,程序性能更好。

        防止利用反射破坏单例:虽然构造方法私有化了,但还是可以通过反射创建实例,这样就破坏了单例对象的唯一性。

          解决方法:构造方法检查,若实例 !=null,抛出异常,不能创建实例对象。

      三、单例实现方式

        饿汉式

        懒汉式

        序列化式  写readResolve(),可避免序列化破坏单例

        枚举式:是最推荐的写单例的方式。

        容器式

        threadlocal线程单例:threadlocal不能保证其创建的对象是全局唯一,但可以保证单个线程内是唯一的,天生的线程安全。

          经过多线程测试发现,单个线程的实例对象总是唯一的,多个线程的实例是不同的。通过源码发现,threadlocal将所有对象都放到threadlocalmap中,key是

          线程,value是对象,以空间换时间来实现线程间隔离的。

          伪线程安全,在一个线程内部,线程是安全的,只有一个对象。在一个线程外部,线程不安全,可创建多个对象。

          对threadlocal的应用:Spring源码中,使用它来达到多数据源的动态切换。

      三、其他可能出现问题:

        1.有时单例需被序列化写入磁盘,然后再从磁盘反序列化读出实例对象,此时会创建一个新的对象,破坏了单例对象唯一性,怎么办?

          A1:从JDK源码中,可以看到只需增加readResolve方法就可以解决。JDK考虑到这种情况,已经解决,但虽然返回了原先的实例对象,但从源码可以看到它中

        途有重新创建新的实例对象,浪费了内存资源,显然,这种不是最好的解决方式。

          A2:注册式单例:注册式单例也叫登记式单例,是把每一个实例都注册到某一个地方,使用唯一的标识获取实例。注册式单例有两种写法,

            1)枚举:是天生的写单例的方式,不存在线程安全问题,自动解决序列化反序列化破坏单例,用反射破坏单例的各种问题。特点:简单好用。

              注:将代码反编译查看源码就会发现,枚举式单例在静态代码块中就给实例赋值,是饿汉模式的实现。

                序列化不能破坏单例的原因:查看JDK源码发现,枚举类型实际通过类名和class枚举对象找到一个唯一的枚举对象。因此,枚举对象不能被类

                  加载器多次加载。

                不能被反射破坏的原因:JDK不让枚举类用反射实例化。

            2)容器缓存:容器缓存用于创建实例非常多的情况,便于管理。但它是非线程安全的,可通过加锁实现安全。

  • 相关阅读:
    JS高级-虚拟DOM
    JS高级-异步
    tomcat server.xml中文版
    java中的等于
    eclipse version
    angularjs中父,子,兄之间controller值得传递
    《那一天,那一月,那一年,那一世》-------仓央嘉措
    用jsonp格式的数据进行ajax post请求变成get
    git常用指令
    让div支持placeholder属性/模拟输入框的placeholder属性
  • 原文地址:https://www.cnblogs.com/Lena666/p/11253029.html
Copyright © 2011-2022 走看看