单例实现方式
懒汉式
基本写法
- 直接按以下这种方式写是线程不安全的
static class Singleton{
//私有的静态变量
private static Singleton mInstance = null;
//私有的构造方法
private Singleton(){}
//暴露一个共有静态方法
public static Singleton getInstance(){
if(mInstance == null){
mInstance = new Singleton();
}
return mInstance;
}
}
由于是使用时才创建,多线程环境下可能会有多个线程同时创建 -> 线程不安全
加同步锁
- 方法上加锁 -可以解决线程不安全问题,但同步锁粒度太大
锁的粒度是指锁定共享资源的范围大小。在多线程环境下,当多个线程访问共享资源时,要确保资源的一致性,避免数据竞争和并发错误。锁的粒度会影响到并发程序的性能。
static class Singleton{
//私有的静态变量
private static Singleton mInstance = null;
//私有的构造方法
private Singleton(){}
//暴露一个共有静态方法
public static synchronized Singleton getInstance(){ //同步锁粒度太大
if(mInstance == null){
mInstance = new Singleton();
}
return mInstance;
}
}
- 代码块加锁,
volatile关键字
volatile关键字的作用:1.保持对象在内存中的可见性;2.禁止编译器和处理器为优化对指令进行重排序
static class Singleton{
//私有的静态变量
private volatile static Singleton mInstance = null;
//私有的构造方法
private Singleton(){}
//暴露一个共有静态方法
public static Singleton getInstance(){
if(mInstance == null){
synchronized(Singleton.class){
if(mInstance == null){
mInstance = new Singleton();
}
}
}
return mInstance;
}
}
饿汉式
- 类加载时就被创建,整个应用程序运行期间只创建这一次,可以确保访问到的始终是这个单例
- 优点:线程安全
- 缺点:如果对象较大且未必用得到,会造成资源浪费
static class Singleton{
private static Singleton sInstance = new Singleton();
private SingleTon(){}
public static Singleton getInstance(){
return sInstance;
}
}
静态内部类
- 只有在第一次调用时,单例对象会在静态内部类加载和初始化时被创建
- 优点:既实现了懒汉式的延迟加载,又实现了饿汉式的线程安全
static class Singleton{
private Singleton(){}
private static class Holder{
private static final Singleton INTSTANCE = new Singleton();
}
public static final Singleton getInstance(){
return Holder.INSTANCE;
}
}
枚举类
enum类中的每个元素都会且仅会被创建一次- 优点:线程安全,实现简单,防止反射和序列化重新创建对象
static enum Singleton{
INSTANCE;
}
容器管理单例对象
- 适用于需要管理多个单例实例的场景,可以根据键值对来管理不同的单例对象
Android中如获取NotificationManager应该就是采用这种方式
static class SingletonManager{
private static Map<String,Object> objMap = new HashMap<>();
public static void registerService(String key,Object instance){
if(!objMap.containsKey(key)){
objMap.put(key,instance);
}
}
public static Object getService(String key){
return objMap.get(key);
}
}
这里的总结或多或少有考虑不周之处,欢迎补充和指正!!!