1、基础简介
由于最近项目需求使用到了IO操作,特意花费一定的时间研究了下单例模式,希望对你有用。
定义:
确保某个类只有一个实例,而且自行实例化提供给外部使用。
使用场景:
某个类型的对象只应该有且只有一个,或者避免创建多个对象消耗过多的资源时。
例如:
访问IO或数据库时要考虑单例模式。
2、实现方式
a、饿汉式:作为初学者,笔者在项目中多次使用该方式
public class SingleTon {
private static final SingleTon Instance = new SingleTon();
private SingleTon() {
}
// 提供实例对象
public static SingleTon getInstance() {
return Instance;
}
public void Test() {
}
}
调用:
SingleTon.getInstance().Test();
优点:简单,线程安全
缺点:实例对象是 static 的,在声明的时候就实例化了,浪费资源
b、懒汉式:不建议使用
public class SingleTon {
private static SingleTon Instance;
private SingleTon() {
}
private static synchronized SingleTon getInstance(){
if (null == Instance){
Instance = new SingleTon();
}
return Instance;
}
}
优点:用到的时候才会去实例化,在一定程度上节约了资源
缺点:getInstance 方法是用 synchronized修饰的,每次调用该方法的时候都会被同步,这样会消耗不必要的资源,一般不建议使用
c、Double Check Lock(DCL模式):双重检查锁定,对懒汉模式的优化,建议使用
public class SingleTon {
private static SingleTon singleTonInstance;
private SingleTon() {
}
public static SingleTon getInstance(){
if (singleTonInstance == null){
synchronized (SingleTon.class){
if (singleTonInstance == null){
singleTonInstance = new SingleTon();
}
}
}
return singleTonInstance;
}
}
可以看到getInstance()方法对singleTonInstance进行两次判空,对懒汉式进行了优化,只有在第一次实例化的时候才会走第二个分支,才会同步,避免了每次都同步造成的不必要的资源消耗
优点:第一次执行getInstance方法时才会实例化,资源利用率高,效率高。
缺点:偶尔失效(高并发条件下,由于JDK版本问题,在jdk1.5之前会失败)
d、静态内部类实现:建议使用
public class SingleTon {
private SingleTon() {
}
public static SingleTon getInstance() {
return SingleTonHoulder.singleTonInstance;
}
// 静态内部类
public static class SingleTonHoulder {
private static final SingleTon singleTonInstance = new SingleTon();
}
}
第一次调用getInstance()方法的时候,虚拟机才会加载SingleTonHoulder静态内部类
优点:线程安全,保证单例的唯一性,延迟了对象的实例化,是推荐的方式
总结:
单例模式是使用频率较高的设计模式,但是由于客户端通常没有高并发的情款,选择哪种实现方式并不会有太大影响;
但是,出于效率考虑,推荐使用“DCL”和“静态内部类”实现方式。
refer:
https://blog.csdn.net/anyanyan07/article/details/72039601