版权声明:本文为博主原创,未经博主允许不得转载。 https://blog.csdn.net/weixin_36904568/article/details/89923575
1. 定义
确保类中只有一个实例,由自己创建,并且提供一个全局访问点
2. 使用
(1)即时实现(饿汉式)——空间换时间
- 私有构造器
- 私有静态变量:初始化为具体对象,记录唯一实例
- 公共静态构造方法
- 返回唯一实例
package SingletonPattern;
/**
* 即时单例
*/
public class ImmediatelySingletion {
//一开始就创建
private static ImmediatelySingletion singletion = new ImmediatelySingletion();
private ImmediatelySingletion(){}
public static ImmediatelySingletion getInstance(){
return singletion;
}
}
(2)延时实现(懒汉式)——时间换空间
- 私有构造器
- 私有静态变量:初始化为空值,记录唯一实例
- 公共静态构造方法:检查是否存在实例
- 创建唯一实例
- 返回唯一实例
package SingletonPattern;
/**
* 延时实现
*/
public class DelayedSingleton {
//暂未初始化
private static DelayedSingleton singleton;
private DelayedSingleton(){}
public static DelayedSingleton getInstance(){
if (singleton == null)
singleton = new DelayedSingleton();
return singleton;
}
}
(3)枚举
单元素的枚举类型已经成为实现Singleton的最佳方法。用枚举来实现单例非常简单,只需要编写一个包含单个元素的枚举类型即可。
package SingletonPattern;
/**
* 枚举类
*/
public enum EnumSingleton {
//枚举单元素
singleton;
public void operation(){
System.out.println("枚举类的业务逻辑");
}
}
3. 多线程
(1)即时实现
(2)延迟实现
使用synchorized修饰公共静态构造方法
public static synchronized DelayedSingleton getInstance(){
if (singleton == null)
singleton = new DelayedSingleton();
return singleton;
}
特点:效率低,在每次创建实例的时候都会同步
(3) 双重检查加锁
- 使用volatile修饰私有静态变量
- 公共静态构造方法
- 第一重检查: 检查是否存在实例
- 第二重检查:进入同步块过后,再次检查实例是否存在
- 创建唯一实例
- 返回唯一实例
package SingletonPattern;
/**
* 双重加锁检查
*/
public class DuplicationCheck {
//不会被本地线程缓存
private static volatile DuplicationCheck singleton;
private DuplicationCheck(){}
public static DuplicationCheck getInstance(){
if (singleton == null){
synchronized (DuplicationCheck.class){
if (singleton == null)
singleton = new DuplicationCheck();
}
}
return singleton;
}
}
特点:volatile关键字可能会屏蔽掉虚拟机中一些必要的代码优化,效率较低
(4) Lazy initialization holder class模式
类级内部类:由static修饰的成员式内部类
多线程缺省同步锁:由静态初始化器(在静态字段上或static{}块中的初始化器)初始化数据时会自动同步
package SingletonPattern;
/**
* 通过静态内部类创建对象
*/
public class StaticInnerClass {
private StaticInnerClass(){}
/**
* 被调用时才会加载,由JVM保护线程安全
*/
private static class holderClass{
private static StaticInnerClass singleton = new StaticInnerClass();
}
public static StaticInnerClass getInstance(){
return holderClass.singleton;
}
}