美文网首页Android知识
设计模式1——单例模式

设计模式1——单例模式

作者: 头发依然在 | 来源:发表于2017-11-10 17:39 被阅读16次

    前记:本文主要是学习笔记,如有哪里写的不对,还希望大家指出,予以改正。
    说起单例模式,现在网上百度一搜一大把,本文主要是参考拭心大神的文章,进行学习和总结。
    接下来来说正事。

    1、解释

    所谓的单例模式就是保证某个类只能被创建一次,而且以后在使用这个类的时候只能使用这个类对象。比如电脑上的任务管理器、Android中的application等。

    2、作用

    单例模式就是为了保证某个状态一致性,在某个位置改变了该类对象的状态,在其他地方使用的时候引用最新的状态。

    单例之-----懒汉模式
    上代码:
    public class TextActivity {
        TextActivity inStance = null;
        //防止通过构造器创建,将构造器改成私有的
        private TextActivity() {
        }
    
        public TextActivity getInstance() {
            if (inStance == null) {
                inStance = new TextActivity();
            }
            return inStance;
        }
    }
    

    注:
    将构造器定义为私有的, 可以有效防止通过构造器创建对象。同时,这种方式虽然实现起来简单,但是在线程上是不安全的,当多线程同时访问时,由于线程的不确定性,可能会创建多个对象,在使用时产生混乱。

    单例之-----懒汉模式的进化(加锁控制的单例模式)

    为了避免上述问题(线程不安全),可以在懒汉模式的基础上增加同步锁进行控制。但是如果只是简单的锁控制,在多线程访问时,出现线程2需要在线程1访问完才能访问,线程3等待线程2......这样一直等待太耗时间,所以就进一步优化,只有在该类对象没有被创建的时候才进行锁控制,有实例对象的时候直接返回该实例(上代码):

    public class TextActivity {
        static TextActivity inStance = null;
    
        //防止通过构造器创建,将构造器改成私有的
        private TextActivity() {
        }
    
        public static TextActivity getInstance() {
            if (inStance == null) {
                createInstance();//使用同步锁控制
            }
            return inStance;
        }
    
        //同步锁控制
        public synchronized static void createInstance() {
            if (inStance == null) {
                inStance = new TextActivity();
            }
        }
    }
    

    注:
    这种方式虽然保证了实例的唯一性,但是在多线程的情况下并没有保证创建的先后顺序。正常情况下,我们是在主线程中对类对象进行创建,其他线程访问我们创建好的,这样前面的问题就不存在了,如果要在多线程中访问,就不安全,就要在类方法创建时进行初始化,而不是调用时才初始化。

    单例之-----饿汉式单例

    该模式使用了static的预先加载的特性
    被static修饰的成员变量和成员方法独立于该类的任何对象,也就是说它不依赖特定的实例,被类的所有实例共享,只要这个类被加载了,java虚拟机就能根据类名在运行时数据区的方法区找到他们,因此static对象可以在它的任何对象创建之前访问,无需引用任何对象。
    这种方式基于classloader机制,避免了多线程的同步问题,在类加载的同时就已经创建了一个静态的对象供系统使用,以后不会再改变,所以线程是安全的。在这种思路下就引发了新的单例模式的编写方法:

    上代码:
    public class TextActivity {
        static TextActivity inStance = new TextActivity();
    
        //防止通过构造器创建,将构造器改成私有的
        private TextActivity() {
        }
    
        public static TextActivity getInstance() {
            return inStance;
        }
    }
    

    注:
    这种方式有个缺点:不能从外部进行初始化,对象都是写死的,但是很多大牛都推荐这样写。

    总结

    单例模式的编写模式、方式多,但是可以根据实际情况选择适合自己应用场景的,大部分情况下是不会在多线程中使用的,不过也不排除这种情况。假如我们使用前两种方式,可以在主线程中创建实例,这样在多线程引用时就已经存在了类对象,就不会出现上文中提到的问题。所以解决问题重要的是有思路,解决问题的方式不是一成不变的。

    外篇:(一起共同学习进步)
    QQ群:541144061

    image.png

    微信群:加我好友,写好备注:android技术经验分享

    image.png

    相关文章

      网友评论

        本文标题:设计模式1——单例模式

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