博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式-单例模式
阅读量:5225 次
发布时间:2019-06-14

本文共 2360 字,大约阅读时间需要 7 分钟。

单例模式就是在访问某个类的时候它只有唯一的实例

单例模式有很多好处,它能够避免实例对象的重复创建,不仅可以减少每次创建对象的时间开销,还可以节约内存空间;能够避免由于操作多个实例导致的逻辑错误。如果一个对象有可能贯穿整个应用程序,而且起到了全局统一管理控制的作用,那么单例模式也许是一个值得考虑的选择。

java常见的单例模式

1.饿汉单例

    饿汉单例模式,顾名思义,就是类加载的时候实例化一个对象出来

    代码实现:

      

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

  优点:类构造为private,保证了外部类不能构造它

       在类加载的时候创建好一个实例,不存在多线程创建多个实例的问题

  缺点:初始化的时候构造,如果该单例未被使用,浪费内存资源

2.懒汉单例

  懒汉单例模式解决了饿汉单例模式的缺点,在使用的时候再对它进行实例化

  代码实现:

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

    由于懒汉单例模式并没有考虑线程安全,故加synchronized?,来保证线程安全

    优点:按需创建,节约资源

    缺点:加了线程锁,多线程环境初始化的时候性能不好

3.登记单例(spring单例实现是登记单例和双重锁的实现)

 4.双重校验锁

    为解决加锁懒汉单例引起的性能问题,出现了双重校验锁单例,

    代码实现如下:

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

    优点:在懒汉模式的基础上,解决了多线程并发的性能问题

    缺点:java指令重排优化引起错误,

指令重排:

      重排优化是指在不改变原语义的情况下,通过调整指令的执行顺序让程序运行的更快。JVM中并没有规定编译器优化相关的内容,也就是说JVM可以自由的进行指令重排序的优化。这个问题的关键就在于由于指令重排优化的存在,导致初始化Singleton和将对象地址赋给instance字段的顺序是不确定的。在某个线程创建单例对象时,在构造方法被调用之前,就为该对象分配了内存空间并将对象的字段设置为默认值。此时就可以将分配的内存地址赋值给instance字段了,然而该对象可能还没有初始化。若紧接着另外一个线程来调用getInstance,取到的就是状态不正确的对象,程序就会出错。

  解决方案:加volatile,加volatile的一个语义是禁止指令重排序优化,也就保证了instance变量被赋值的时候对象已经是初始化过的,从而避免了上面说到的问题

  volatile详解

    首先我们要先意识到有这样的现象,编译器为了加快程序运行的速度,对一些变量的写操作会先在寄存器或者是CPU缓存上进行,最后才写入内存.

    而在这个过程,变量的新值对其他线程是不可见的.而volatile的作用就是使它修饰的变量的读写操作都必须在内存中进行!

5.静态内部类

    代码实现:

public class Singleton{      private static class SingletonHolder{          public static Singleton instance = new Singleton();      }      private Singleton(){}      public static Singleton newInstance(){          return SingletonHolder.instance;      }  }

 

    优点:内部类自己实现,保证延迟加载,保证线程安全

 

转载于:https://www.cnblogs.com/nanguabushuohua/p/7606250.html

你可能感兴趣的文章
数据结构测试2 on 2019.9.25
查看>>
有道词典_每日一句_2019/07
查看>>
微信小程序 base64格式图片的显示及保存
查看>>
有道词典_每日一句_2019/08
查看>>
微信小程序 报错Failed to load image
查看>>
读书_2019年
查看>>
有道词典_每日一句_总贴
查看>>
读书汇总贴
查看>>
有道词典_每日一句_2019/09
查看>>
微信小程序 movable-view组件应用:可拖动悬浮框_返回首页
查看>>
微信公众号_Deejo说_2019
查看>>
ASC47B borderless
查看>>
MPT树详解
查看>>
最适合程序员转行的10大职业
查看>>
空间分析开源库GEOS
查看>>
RQNOJ八月赛
查看>>
数据表设计
查看>>
alluxio
查看>>
关于ajax回调数据类型为Json,如何获得他的值
查看>>
前端各种mate积累
查看>>