Android 单例模式学习

android的单例模式学习

1 饿汉单例模式

public class AppUtils_0 {
    
    private static final AppUtils_0 APP_UTILS_0 = new AppUtils_0();

    private AppUtils_0() {
        Log.e("text123", "AppUtils_0: " );
    }

    public static AppUtils_0 getInstance() {
        return APP_UTILS_0;
    }

 }

优点 :

        类在被加载的时候,单件模式实例就已经被创建。
        如果单件模式实例在系统中经常会被用到,饿汉式是一个不错的选择。

缺点 :

         类在被加载的时候,单件模式实例就已经被创建,会占用资源
         如果此类用的不是很频繁就亏了 

2.0 懒汉模式

public class AppUtils_1 {
   
   private static AppUtils_1 APP_UTILS_1;

   public static synchronized AppUtils_1 getInstance () {
       if (APP_UTILS_1 == null) {
           APP_UTILS_1 = new AppUtils_1();
       }

       return APP_UTILS_1;
   }
}

优点 :

        这样写的单例模式只有在使用的时候才会被实例化,在一定程度上节约了资源

缺点 :

         第一次加载的时候需要及时进行实例化,反应稍慢,最大的问题是每次调用getInstance 的时候都会同步
         这样就会造成不必要的同步开销,所以这样的写法不建议使用.

2.1 懒汉模式 (改进版)

public class AppUtils_1_1 {
   private static AppUtils_1_1 APP_UTILS_1_1;

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

对比

     相对对于上一个模式这个模式在getInstance方法中对instance进行了两次判空
     第一次判断是为了避免不必要的同步 第二次就是为了判断在null的情况下创建实例
     这样就避免了反复同步也达到了单例的要求.

隐患

     这个写法大概做了3件事情
     1 给AppUtils 的实例分配内存
     2 调用AppUtils的构造函数,初始化成员字段
     3 将APP_UTILS_1_1对象指向分配的内存空间
     但是 java的编译器允许处理器乱序执行以及Cache,
     寄存器到内存回写内存顺序规定上面的 2 和3 是没有先后的顺序的
     就是说 执行顺序可以是 123 也可以是132 
     就是在两个线程中同时执行getInstance()函数 假设a线程在执行很快 APP_UTILS_1_1就不会是空了 
     b线程就会直接取走APP_UTILS_1_1在使用就会有问题了

优点 :

        资源利用率高,第一次执行getInstance是单例对象才会被实例化

缺点 :

         第一次加载反应稍慢,也由于java内存模型的原因偶尔加载失败
         在高并发环境下也有一定的缺陷,虽然概率小

3 静态内部单例模式

public class AppUtils_2 {
    
    private AppUtils_2() {
    }
    private static class AppUtils_2Holder {
        private static final AppUtils_2 UTILS_2 = new AppUtils_2();
    }

    public static AppUtils_2 getInstance() {
        return AppUtils_2Holder.UTILS_2;
    }
}

说明 :

       当第一次加载AppUtils_2类是并不会初始化 UTILS_2 只有在第一次调用AppUtils_2的getInstance
       才会初始化 UTILS_2 类 因此第一次调用getInstance会导致虚拟机加载AppUtils_2Holder类
       这样的方法不仅保证线程安全也能保证单例对象唯一性同时也实现了单例的实例化
       所以推荐使用这个方法

static在内存中是怎么分配的

为什么静态修饰后反复获取这个类 就是唯一的一个呢?在内存中有是怎么存放的呢?

Java的堆是一个运行时数据区,类的对象从中分配空间。
这些对象通过new、newarray、anewarray和multianewarray等指令建立,
它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,
堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,
因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。
但缺点是,由于要在运行时动态分配内存,存取速度较慢.

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。
但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量
(int, short, long, byte, float, double, boolean, char)和对象句柄。

一般的类 在申明的时候在栈中设置一个地址存放的是为null的应用
在XX xx = new XX();的时候会在堆中分配内存存放xx 然后堆中的引用指向这个地址

static

内存不止分为堆和栈,还有另外3个区,
静态变量在静态存储区 所以所有的静态变量和静态内都是在这个静态区的

一个类中,一个static变量只会有一个内存空间,虽然有多个类实例,但这些类实例中的这个static变量会共享同一个内存空间.
就是说XX类 有很多new出来的类 xx_0 xx_1; 但是XX类中的static修饰的 变量 在xx_0 或者xx_1 中都是一个地址
所以这才是单例模式的原理

参考地址 https://www.cnblogs.com/avivahe/p/5747127.html

参考地址 https://blog.csdn.net/qianyayun19921028/article/details/80365126

参考地址 https://www.jianshu.com/p/202f6abb229c

q 静态内部内 中也存在静态变量和非静态变量 这些内存有是怎么分配的呢?
a :静态内部类中的静态变量也是在方法区中的,
这里我们可以把静态内部类看成一 个类这个类本身是在堆区的(他和类是平级的)静态内部类的加载和一般的类也是一样的
q 接口类 和接口函数是如何分配内存的?
a :看接口的调用他是在有实例化的情况才能使用函数 但是他的常量是默认用静态 修饰的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容