GitHub源码分享
微信搜寻:码农StayUp主页地址:https://gozhuyinglong.github.io
源码分享:https://github.com/gozhuyinglong/blog-demos
1. 单例模式
单例模式(Singleton Pattern)是一种简略的对象创立型模式。该模式保障一个类仅有一个实例,并提供一个拜访它的全局拜访点。
所以要实现单例模式,要做到以下几点:
- 将构造方法私有化,杜绝应用结构器创立实例。
- 须要本身创立惟一的一个实例,并提供一个全局拜访入口
2. 单例模式的几种实现
对于单例模式有以下5种实现。
2.1. 懒汉式
该形式是应用synchronized
关键字进行加锁,保障了线程安全性。
长处:在第一次调用才初始化,防止了内存节约。
毛病:对获取实例办法加锁,大大降低了并发效率。
因为加了锁,对性能影响较大,不举荐应用。
public class SingletonLazy { /** * 公有实例 */ private static SingletonLazy instance; /** * 公有构造方法 */ private SingletonLazy() { } /** * 惟一公开获取实例的办法(动态工厂办法),该办法应用synchronized加锁,来保障线程安全性 * * @return */ public static synchronized SingletonLazy getInstance() { if (instance == null) { instance = new SingletonLazy(); } return instance; }}
2.2 饿汉式
饿汉式是利用类加载机制来防止了多线程的同步问题,所以是线程平安的。
长处:未加锁,执行效率高。
毛病:类加载时就初始化实例,造成内存节约。
如果对内存要求不高的状况,还是比拟举荐应用这种形式。
public class SingletonEager { /** * 公有实例,动态变量会在类加载的时候初始化,是线程平安的 */ private static final SingletonEager instance = new SingletonEager(); /** * 公有构造方法 */ private SingletonEager() { } /** * 惟一公开获取实例的办法(动态工厂办法) * * @return */ public static SingletonEager getInstance() { return instance; }}
2.3 双重校验锁
利用了volatile修饰符的线程可见性(被一个线程批改后,其余线程立刻可见),即保障了懒加载,又保障了高性能,所以举荐应用。
public class SingletonDCL { /** * 公有实例,volatile润饰的变量是具备可见性的(即被一个线程批改后,其余线程立刻可见) */ private volatile static SingletonDCL instance; /** * 公有构造方法 */ private SingletonDCL() { } /** * 惟一公开获取实例的办法(动态工厂办法) * * @return */ public static SingletonDCL getInstance() { if (instance == null) { synchronized (SingletonDCL.class) { if (instance == null) { instance = new SingletonDCL(); } } } return instance; }}
2.4 动态外部类
该模式利用了动态外部类提早初始化的个性,来达到与双重校验锁形式一样的性能。因为须要借助辅助类,并不罕用。
public class SingletonInnerClass { /** * 公有构造方法 */ private SingletonInnerClass() { } /** * 惟一公开获取实例的办法(动态工厂办法) * * @return */ public static SingletonInnerClass getInstance() { return LazyHolder.INSTANCE; } /** * 公有动态外部类 */ private static class LazyHolder { private static final SingletonInnerClass INSTANCE = new SingletonInnerClass(); }}
2.5 枚举类
该形式利用了枚举类的个性,不仅能防止线程同步问题,还避免反序列化从新创立新的对象。这种形式是 Effective Java 作者 Josh Bloch 提倡的形式。
但因为这种编码方式还不能适应,所以理论工作中很少应用。
public enum SingletonEnum { INSTANCE; public void method() { System.out.println("枚举类中定义方法!"); }}