android源码设计模式学习之单列模式

单列对象的类必须保证一个实例存在,而且自行实例化并向整个系统提供这个实例

使用场景:确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有且只有一个,如访问数据库

使用单列模式的关键点:
(1)构造函数不对外开放,一般为private
(2)通过一个静态方法或者枚举返回单列对象
(3)确保单列对象有且只有一个,尤其多线程环境下
(4)确保单列对象在反序列化时不会重新构建对象

(一)饿汉式

public class IOUtil {
    
    
    private static final IOUtil INSTANCE = new IOUtil();
    private IOUtil(){
    
    }
    public static IOUtil getInstance(){
    
    
        return INSTANCE;
    }
}

(二)懒汉式
是声明一个静态对象,并且在用户第一次调用getInstance时初始化

public class IOUtil {
    
    
    private static IOUtil INSTANCE = null;
    private IOUtil(){
    
    } 
    public static synchronized IOUtil getInstance(){
    
    
        if (INSTANCE == null){
    
    
            INSTANCE = new IOUtil();
        }
        return INSTANCE;
    }
}

getInstance()方法中添加一个synchronized关键字,也就是getInstance的一个同步方法,者就是在多线程情况下保证单列对象唯一性的手段。但是,每次使用getInstance时都会synchronized同步,会造成不必要的同步开销,所以建议不使用多线程时,不使用该关键字

(三)DCL实现单列
DCL实现单例模式的优点是既能在需要时才初始化单列,又能保证线程安全,且单列对象初始化后调用getInstance不进行同步锁

public class IOUtil {
    
    
    private static IOUtil INSTANCE = null ;

    private IOUtil(){
    
    }

    public static IOUtil getInstance(){
    
    
        if (INSTANCE == null){
    
    
            synchronized (IOUtil.class){
    
    
                if (INSTANCE == null){
    
    
                    INSTANCE = new IOUtil();
                }
            }
        }
        return INSTANCE;
    }
}

优点:资源利用率高
缺点:第一次加载时反应慢

(四)静态内部类单列模式
DCL虽然在一定程度上解决了消耗资源,多余的同步,线程安全等问题,但是,它还是在某些情况下出现失效的问题,不赞成使用

public class IOUtil {
    
    

    public static IOUtil getInstance(){
    
    
        return SingleHolder.INSTANCE;
    }
    
    private static class SingleHolder{
    
    
        public static final IOUtil INSTANCE = new IOUtil();
    }
}

当第一次加载IOutil类时并不会初始化INSTANCE ,只有在第一次调用getInstance时才会导致INSTANCE被初始化,这种方式不仅保证线程安全,也能保证单例对象的唯一性,推荐使用。

(五)使用容器实现单例模式

public class IOUtil {
    
    
    private static HashMap<String,Object> hashMap = new HashMap<>();

    public static void registerService(String key,Object object){
    
    
        if (!hashMap.containsKey(key)){
    
    
            hashMap.put(key,object);
        }
    }

    public static Object getService(String key){
    
    
        return hashMap.get(key);
    }
}

Android源码中的单列模式
在Android系统中,我们经常会通过Context获取系统级别的服务,如WindowManagerService ,ActivityManagerService等。更常用的是LayoutInflater的类,LayoutInflater较为常见的地方是在ListView的getView方法中

View view = LayoutInflater.from(mContext).inflate(layoutId,null);

可以看到的form(Context)函数内部调用的是Context类的getSystemService(String key)方法,我们继续看

猜你喜欢

转载自blog.csdn.net/qq_42447739/article/details/126256178
今日推荐