Android中单例模式
来源:互联网 发布:怎么把mac照片导入u盘 编辑:程序博客网 时间:2024/06/11 13:47
设计模式系列:
0. Android开发常用设计模式;
1. Android中单例模式;
2. Android中建造者(builder)模式;
3. Android中观察者模式;
4. Android中原型模式;
5. Android中策略模式;
6. Android中工厂模式;
7. Android中代理模式;
8. Android中装饰者模式;
9. Android中适配器模式;
单利模式定义:核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。
一、常见需求场景
三毛:“小白,你对后台返回来的json数据解析是用json还是Gson吖”
小白:我是用的Gson解析后台返回来的数据,怎么了?
二、基本解决方法
三毛:“那你是怎样使用Gson的呢”
小白:因为我一般都是拿到后台给的json字符串数据,然后转换成实体类对象,就像下面拿到json字符串jsonStr,然后转换成实体类A
//初生牛犊不怕虎的(普通写法) Gson gson = new Gson(); A aBean = gson.fromJson(jsonStr, A.class);
三、基本解决方法存在的问题
三毛:“我的白,你这样new,new,new,一两个没啥问题,但是几十个,几百个,会存在内存占用多和不同对象对同一个资源的操作的问题波”
小白:毛毛哥说得是,确实是这样,那我给Gson写一个类,然后调用它来解析,像下面那样
//饿汉式单例写法public class GsonSingle { private static Gson mGson = new Gson(); private GsonSingle() {//构造函数设置为private,防止外部程序通过new来构造 } public static Gson getInstance() { return mGson; }}//调用gson单利类来解析 A aBean = GsonSingle.getInstance().fromJson(jsonStr, A.class);
三毛:”白啊,你这样确实解决了一直new,new,new的问题,假设你这个GsonSingle类不使用getInstance静态方法的时候,而是使用其他静态方法,那你静new出来的静态实例不就浪费内存资源了嘛”
小白:啪啪啪(敲键盘),我改成下面那样子,毛毛哥看看这下Ok了吧
//懒汉式写法public class GsonSingle { private static Gson mGson = null; private GsonSingle() { } public static Gson getInstance() { if (mGson == null) { mGson = new Gson(); } return mGson; }}
三毛:“你这样写,正常来看是没什么问题,但是在多线程的情况下就会出现另外的问题,多线程并发,线程不安全的情况呢”;
小白:那我给它加个锁synchronized,变成下面那样子,怎么样,这下没什么好说的了吧;
//懒汉式枷锁写法public class GsonSingle { private static Gson mGson = null; public static synchronized Gson getInstance() { if (mGson == null) { mGson = new Gson(); } return mGson; }}
三毛:“嘿嘿,这样加锁确实处理了多线程并发的问题,但是当你次次获取单例都同步,那不和前面一样,造成资源浪费了吗,也就是说等于没啥子改进的啵”
小白:有点道理,啪啪啪(敲键盘),好了,调下位置,改成下面那样,这样一来就不会次次都因为同步造成资源浪费了吧
//懒汉式双重枷锁写法public class GsonSingle { private static Gson mGson = null; private GsonSingle() { } public static Gson getInstance() { //先检查实例是否存在,如果不存在才进入下面的同步块 if(mGson == null){ //同步块,线程安全地创建实例 synchronized(Gson.class){ //再次检查实例是否存在,如果不存在才真正地创建实例 if(mGson == null){ mGson = new Gson(); } } } return mGson; }}
三毛:“嗯,是的,不过你这样写第一次加载类的时候还是需要同步,也就意味着第一次加载类会牺牲一点时间,你觉得还能改进嘛”
小白:我想不到其他改进的办法了
三毛:“嘿嘿嘿,可能你一时忘记了,其实可以用内部类来写单例,像下面这样”
//内部类单例写法public class GsonSingle { private GsonSingle() { } public static Gson getInstance() { return GsonSingleHolder.gson; } private static class GsonSingleHolder { private static final Gson gson = new Gson(); }}
小白:握草,居然还有这种操作,三毛哥,你平常的单例都是用这中内部类的方式吗?
三毛:“大部分都是用的内部类写单例,也有时候偷懒,像你第一种方式直接在类里new一个静态对象,不过我还是看情况来选择,另外你上面的改进也是属于单例设计模式中的几种写法,其实还有网络江湖上流传的另外2中写法你可能没想到,那就是枚举单例和容器单例”
小白:嗷嗷嗷,和毛毛哥聊天又学到东西了,我看看枚举单例和容器单例去~~
四、单例模式和普通写法的区别
1.一个类只有一个实例;
2.自己创建这个实例;
3.整个系统只能用这个实例;
4.内存开销减少了,降低多个对象访问同一个资源造成并发问题情况。
- Android中单例模式
- Android模式- Builder模式
- Android中单例模式的多种写法
- Android中单例模式应用实战详解
- Android设计模式--适配器模式
- android设计模式--外观模式
- android设计模式-策略模式
- android设计模式-观察者模式
- android设计模式-工厂模式
- android设计模式-适配器模式
- android设计模式-组合模式
- android 设计模式 状态模式
- android 设计模式-组合模式
- Android 设计模式-----单利模式
- Android设计模式--观察者模式
- Android设计模式--适配器模式
- Android设计模式-适配器模式
- Android设计模式-适配器模式
- TCP和UDP的"保护消息边界" (经典)
- Kafka 详解 + 集群部署
- 欢迎使用CSDN-markdown编辑器
- 软件测试概念
- 由VMware卸载引出CCleaner
- Android中单例模式
- Nginx配置实例
- 粘性定位------------------position:sticky
- C语言-指针
- Vue.js自定义指令的用法与实例
- Debian/Ubuntu上如何使用APT包管理工具
- d3d11的转换-两个立方体发生旋转
- Hadoop
- Spring ActiveMQ 整合(二.1): 重发机制概念解释