- 核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点
## 优点
- 由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决
- 单例模式可以在系统设置全局的访问点,优化环共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理
## 常见的五种单例模式实现方式:
### 主要
- 1. 饿汉模式(线程安全,调用效率高,不能延迟加载)
- 2. 懒汉模式(线程安全,调用效率不高,可以延迟加载) + synchronized
### 其他
- 1. 双重检测锁式(由于JVM底层内部模式原因,偶尔会出问题。不建议使用)
- 2. 静态内部类式(线程安全,调用效率高。可以延迟加载)
- 3. 枚举单例(线程安全,调用效率高,不能延时加载)
饿汉式单例模式:
/**
* 饿汉式单例模式
*/
public class HungrySingleStyleMode {
// 立即加载。加载类时,是线程安全的
private static HungrySingleStyleMode instance = new HungrySingleStyleMode();
// 私有化构造方法
private HungrySingleStyleMode(){}
// 调用效率高
public static HungrySingleStyleMode getInstance(){
return instance;
}
}
懒汉式单例模式:
/**
* 懒汉式单例模式
* @Author: Jadan-Z
*/
public class LazySingleStyleMode {
// 无需初始化对象
private static LazySingleStyleMode instance;
// 私有化构造方法
private LazySingleStyleMode(){}
// 线程安全,需要时才初始化,调用效率低
public static synchronized LazySingleStyleMode getInstance() {
if (null == instance) {
instance = new LazySingleStyleMode();
}
return instance;
}
}
双重锁实现单例模式:
/**
* 双重检查锁
* @Author: Jadan-Z
* @Date: 2019/1/13 14:22
*/
public class DoubleDetectionLockSingletonMode {
// 无需初始化对象
private static DoubleDetectionLockSingletonMode instance;
// 私有化构造方法
private DoubleDetectionLockSingletonMode(){}
// 线程安全,需要时才初始化,调用效率低
public static synchronized DoubleDetectionLockSingletonMode getInstance() {
if (null == instance) {
DoubleDetectionLockSingletonMode sc;
synchronized (DoubleDetectionLockSingletonMode.class) {
sc = instance;
}
if (sc == null) {
synchronized (DoubleDetectionLockSingletonMode.class) {
if (sc == null) {
sc = new DoubleDetectionLockSingletonMode();
}
instance = sc;
}
}
}
return instance;
}
}
静态内部类实现单例模式:
/**静态内部类实现单例模式
* 线程安全,调用效率高,并且实现了延时加载
* @Author: Jadan-Z
* @Date: 2019/1/13 14:29
*/
public class StaticInnerClassSingletonMode {
/**
* 外部类没有static属性,则不会向饿汉式那样立即加载对象
* 只有真正调用getInstance(), 才会加载静态内部类。加载类时是线程安全的。
* instance是static final类型,保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全性。
* 兼备了并发高效调用和延迟加载的优势。
*/
private static class SingletonClassInstance {
private static final StaticInnerClassSingletonMode instance = new StaticInnerClassSingletonMode();
}
// 提供外部调用
public static StaticInnerClassSingletonMode getInstance() {
return SingletonClassInstance.instance;
}
// 私有化构造方法
private StaticInnerClassSingletonMode(){}
}
枚举式实现单例模式:
/**
* 枚举式实现单例模式(没有延迟加载)
* @Author: Jadan-Z
*/
public enum EnumerationSingletonMode {
// 这个枚举元素,本身就是单例对象
INSTANCE;
// 自己添加的操作....singletonOperation这只是个例子
public void singletonOperation() {
}
}
测试方法:
public class SingletonTest {
public static void main(String[] args) {
// 饿汉式实现单例模式
HungrySingleStyleMode singleton1 = HungrySingleStyleMode.getInstance();
HungrySingleStyleMode singleton2 = HungrySingleStyleMode.getInstance();
System.out.println(singleton1 == singleton2);
// 懒汉式实现单例模式
LazySingleStyleMode la1 = LazySingleStyleMode.getInstance();
LazySingleStyleMode la2 = LazySingleStyleMode.getInstance();
System.out.println(la1 == la2);
// 双重锁实现单例模式
DoubleDetectionLockSingletonMode dm1 = DoubleDetectionLockSingletonMode.getInstance();
DoubleDetectionLockSingletonMode dm2 = DoubleDetectionLockSingletonMode.getInstance();
System.out.println(dm1 == dm2);
// 静态内部类实现单例模式
StaticInnerClassSingletonMode sm1 = StaticInnerClassSingletonMode.getInstance();
StaticInnerClassSingletonMode sm2 = StaticInnerClassSingletonMode.getInstance();
System.out.println(sm1 == sm2);
// 枚举式实现单例模式
EnumerationSingletonMode em1 = EnumerationSingletonMode.INSTANCE;
EnumerationSingletonMode em2 = EnumerationSingletonMode.INSTANCE;
System.out.println(em1 == em2);
}
}