美文网首页
android开发-五种单例模式

android开发-五种单例模式

作者: 代码界的泥石流 | 来源:发表于2018-03-03 00:21 被阅读0次

废话不多说 直接上代码

  • 饿汉式
public class MyApplication extends Application {

    private MyApplication() {
    }
    private static MyApplication app = new MyApplication();

    public static MyApplication getInstance() {
        return app;
    }
}

类加载就会创建实例,线程安全。因为虚拟机保证了类只会加载一次,在装载类的时候是不会并发的
缺点:无法携带参数 无法实现延迟加载

  • 懒汉式
public class MyApplication extends Application {


    private MyApplication() {
    }

    private static MyApplication app;

    public static MyApplication getInstance() {
        if (app == null) {
            app = new MyApplication();
            return app;
        }
        return app;
    }
}

适合单线程模式 延迟加载
缺点:多线程调用情况下,会出现多个实例。例如:当两个线程同时运行到判断app是否为空的if语句,并且app确实没有创建完毕,那么两个线程都会创建一个实例
优点:可携带参数 延迟加载

  • 双重锁版本(推荐)
public class MyApplication extends Application {


    private MyApplication() {
    }

    private volatile static MyApplication app;

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

        }
        return app;
    }
}

注意:

  • volatile修饰意思是怕出现多CPU处理出现并发问题 ,可能引发错乱等多个实例的问题 建议查下volatile关键字。
  • synchronized修饰意思是必须线程是排队一个一个进去的,处理了多线程的问题,同时加锁会很耗时的操作,但是不得不为之
  • 第一个IF是判断需不需要 进入加锁判断 如果有实例直接返回实例,第二个IF是来判断是否为null(因为用了synchronized,不会出现多线程的情况,所以保证实例唯一)
  • 内部静态方法类
public class MyApplication extends Application {

    private MyApplication() {
  
   }

    private static class ChildApp {
        private final static MyApplication app = new MyApplication();

    }

    public static MyApplication getInstance() {
        return ChildApp.app;
    }
}

注意:
由于内部类不会在加载外部类的时候进行加载,那么这个也属于懒加载。但是这种延迟加载的加载也是class的加载,jvm保证只有一次所以同样线程安全
优点:效率比双重锁略高
缺点:无法携带参数

  • 枚举(不推荐)
public enum Singleton {  
     INSTANCE;  
     public void whateverMethod() {  
     }  
 }  

枚举不适用于android,谷歌说的。

总结:根据具体需求使用具体单例,比如涉及多线程操作,并且无需携带参数就用内部静态类,如果是带参数那就双重锁等。

相关文章

网友评论

      本文标题:android开发-五种单例模式

      本文链接:https://www.haomeiwen.com/subject/hamzxftx.html