使用场景
使用单例模式的目的:
1、并发访问资源,如windows系统的某个doc文档
2、控制实例产生的数量,如数据库线程池
3、高并发环境下,作为通信的媒介,共享资源内数据
学习自:https://blog.csdn.net/weiwangchao_/article/details/7285211
感兴趣的同学可以看一下,解释的还算透彻
创建方式
单例模式的创建方式,总体归纳来说,只有两类:
- 饿汉模式 ; 对象引用时创建唯一实例,线程安全
- 懒汉模式 ;调用方法时创建唯一实例
饿汉模式
传统创建方式
public class Singleton1 {
private final static Singleton1 SINGLETON_1 = new Singleton1();
public Singleton1(){
}
public static Singleton1 getInstance(){
return SINGLETON_1;
}
}
缺点:实例直接创建,非懒加载模式,造成某些bean创建可能大量耗时
静态块加载
public class Singleton4 {
private final static Singleton4 singleton4;
private Singleton4() { }
static { singleton4 = new Singleton4(); }
public static Singleton4 getInstance() { return singleton4; }
}
改进:实现了懒加载模式
缺点:
静态内部类加载【推荐】
public class Singleton6 {
private Singleton6() { }
private static class SingletonHolder { private static final Singleton6 INSTANCE = new Singleton6(); }
public static Singleton6 getInstance() { return Singleton6.SingletonHolder.INSTANCE; }
}
改进:实现了懒加载模式
缺点:
枚举加载【推荐】
public class Singleton7 {
private Singleton7() { }
enum SingletonEnum {
INSTANCE;
private final Singleton7 singleton7;
private SingletonEnum() { singleton7 = new Singleton7(); }
}
public static Singleton7 getInstance() { return SingletonEnum.INSTANCE.singleton7; }
}
改进:实现了懒加载模式,反序列化对象后也不需要重新创建唯一实例
缺点:
懒汉模式
传统创建方式
public class Singleton2 {
private final static Singleton2 singleton2;
private Singleton2() { }
public static Singleton2 getInstance() {
if (singleton2 == null) singleton2 = new Singleton2();
return singleton2; }
}
缺点:线程不安全,高并发时可能会创建不同的实例
全局锁模式加载
public class Singleton3 {
private final static Singleton3 singleton3;
private Singleton3() { }
public synchronized static Singleton3 getInstance() {
if (singleton3 == null) singleton3 = new Singleton3();
return singleton3; }
}
改进:线程安全
缺点:获取实例时,每次都锁整个对象,高并发时造成不必要耗时
双重校验锁模式加载
public class Singleton5 {
private static volatile Singleton5 singleton5;
private Singleton5() { }
public static Singleton5 getInstance() {
if (singleton5 == null) {
synchronized (Singleton5.class) {
if (singleton5 == null) {
singleton5 = new Singleton5();
}
}
}
return singleton5; }
}
改进:线程安全,只有在实例不存在时,才锁对象创建
缺点:volatile关键字,强制其他线程对实例无写操作时,才可获取。高并发时,对性能可能会有一定的影响。