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("枚举类中定义方法!");
}
}