单例对象(Singleton)是一种常用的设计模式。
在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。
单例模式的核心作用是保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。
单例模式有以下特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
这个模式有几个好处:
1.某些类创建比较繁琐,对于一些大型的对象,这是一笔很大的系统开心。
2.省去了new操作符,降低了系统内存的使用频率,减轻GC压力。
3.有些累比如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。
单例模式的实现过程:
1.构造函数私有化。
2.声明私有的静态实例变量。
3.创建静态的方法用来返回此私有的静态实例变量。
单例模式的五种实现方法:
1.饿汉式:
饿汉式单例模式代码中,static变量会在类装载时初始化,此时也不会设计多个线程对象访问该对象的问题。虚拟机保证只会装载一次该类,肯定不会发生并发访问的问题。因此是线程安全的。
问题是如果只是加载奔雷,而不是要调用getInstance(),深圳永远没有调用,则会造成资源浪费。
2.懒汉式:
懒汉式单例模式代码中提供了lazy load(延时加载,懒加载,真正用的时候才加载)!资源利用率高。
但是每次调用getInstance()方法都要同步,并发效率较低。
3.双重检测锁式:
双重检测锁单例模式将同步内容放到if内部,提高了执行的效率,不必每次获取对象时都进行同步,只有第一次才同步,创建了以后就没必要了。
但是由于编译器优化原因和JVM底层内部模型原因,偶尔会出问题,不建议使用。
4.静态内部类式:
外部类没有static属性,不会像饿汉式那样立即加载对象。
只有真正调用getInstance()方法才会加载静态内部类。加载类时时线程安全的。instance是static final类型,保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全。
兼备了高效调用和延时加载的优势。
5.枚举式:
枚举本身就是单例模式。由JVM从根本上提供保障!避免通过反射和反序列化的漏洞。
枚举式单例模式的缺点是无延迟加载。