安卓单例模式分解

来源:互联网 发布:无纸化会议软件源码 编辑:程序博客网 时间:2024/06/14 14:21

首发安卓设计模式,后期会更加仔细。



安卓单例模式:确保一个类只有一个实例,并且自行实例化想整个系统提供实例。这是单例模式的定义。往往在创建一个对象需要消耗过多的资源,如访问IO和数据库等都可以使用单例。

单例模式主要几点:1构造函数不对外开发,一般为Private;

2通过一个静态方法或枚举返回单例对象;

3确保单例类对象只有一个,尤其是在多线程中

4确保单例类对象在反序列化是不会重新构建对象。


//懒汉式单例类.在第一次调用的时候实例化自己   

public class Singleton {  

    private Singleton() {}  

    private static Singleton sing;  

    //静态工厂方法   

    public static  synchronized Singleton getInstance() {  

         if (single == null) {    

             single = new Singleton();  

         }    

        return single;  

    }  

}  

  你可能知道,getInstance()方法中synchronized关键字,getInstance是一个同步方法,符合了多线程中单例对象一致。但是single即使已经被初始化,每次调用getInstance都会同步进行,消耗了不必要的资源。


这是一个典型的DCL单例,其中volatile在之前已经说过了,可以保证无论何时读取这个变量,都是读到内存中最新的值,无论何时写这个变量,都可以立即写到内存中。


public class Singleton {   

    

    /**  

     * 单例对象实例  

     */  

    private volatile static Singleton instance = null;   

    

    public static Singleton getInstance() {   

        if (instance == null) {   

            synchronized (Singleton.class) {   

                if (instance == null) {   

                    instance = new Singleton();   

                }   

            }   

        }   

        return instance;   

    }   

}


 但是并没有这么简单,在没有见volatile修饰instance时,在编译后,编译器会自动把第二个判断删除,因为编译器判断这个程序在执行过程中,这个值是不会改变的,编译器不考虑多线程的情况。加了volatile,是告诉编译器,这个变量随时有可能会被其他线程改变,这样编译器就不会把这两个判断优化成一个判断了。

DCL优点:资源利用率高,但是第一次加载反应稍慢,由于Java内存模型原因偶尔失败,在高并发环境也有一定缺陷,虽然几率有点小。

/**

*内部静态类实现单例模式

*/

public class Singleton  

{  

    private Singleton(){ }  

      

    public static Singleton getInstance()  

    {  

        return Nested.instance;       

    }  

      

    //在第一次被引用时被加载  

    static class Nested  

    {  

        private static Singleton instance = new Singleton();  

    }  

      

    public static void main(String args[])  

    {  

        Singleton instance = Singleton.getInstance();  

      

    }  

diiic加载类时不会初始化 instance只有在第一次调用 SingletongetInstance()才初始化。这种方式确保线程的安全。



枚举单例

public enum SingIetonEnum{

INSTANCE;

  public void doSomething(){

System.out.println(“do”);

}


}

写法简单,有自己的方法,创建线程也是安全的。


容器实现单例模式


/**

 * 容器单例模式

 * @author josan_tang

 */

public class SingIetonManager {

    private static Map<String, Object> objMap = new HashMap<String, Object>();


  private SingIetonManager(){}

public static void registerService ( String key,Object instance){

if(!objMap.containsKey (key) ){

objMap.put( key ,instance);

}

}

    //根据key从集合中得到单例对象

    public static Object getSingleton(String key) {

        return singletonMap.get(key);

    }

}

在程序的初始,将多种单例类型注入到一个管理类中,在使用是根据key获取对象对应类型的对象,这种方式使得我们可以管理多种类型的单例,并且在使用时可以通过统一的接口进行获取操作,降低了耦合度。

原创粉丝点击