美文网首页
移动开发-单例模式

移动开发-单例模式

作者: 猿侬 | 来源:发表于2018-10-28 22:15 被阅读0次

    简介

    单例模式(Singleton),也叫单子模式,是一种常用的设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候,整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,显然,这种方式简化了在复杂环境下的配置管理

    写法

    1,懒汉式(静态常量)

    public class Singleton {

    private final static Singleton INSTANCE = new Singleton();

    private Singleton(){}

    public static Singleton getInstance(){

    return INSTANCE;

    }

    }

    优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。

    缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。

    2、饿汉式(静态代码块)[可用]

    public class Singleton {

    private static Singleton instance;

    static {

    instance = new Singleton();

    }

    private Singleton() {}

    public static Singleton getInstance() {

    return instance;

    }

    }

    这种方式和上面的方式其实类似,只不过将类实例化的过程放在了静态代码块中,也是在类装载的时候,就执行静态代码块中的代码,初始化类的实例。优缺点和上面是一样的

    3,懒汉式(线程安全,同步方法)

    public class Singleton {

    private static Singleton singleton;

    private Singleton() {}

    public static synchronized Singleton getInstance() {

        if (singleton == null) {

            singleton = new Singleton();

        }

        return singleton;

        }

    }

    缺点:效率太低了,每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步。而其实这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了。方法进行同步效率太低要改进。

    4,饿汉式 双重检查

    public class Singleton {

    private static volatile Singleton singleton;

    private Singleton() {}

    public static Singleton getInstance() {

        if (singleton == null){

            synchronized (Singleton.class) {

                if (singleton == null) {

                    singleton = new Singleton();

                }

            }

        }

        return singleton;

    }

    }

    先不同步,进入方法过后,先检查实例是否存在,如果不存在才进入下面的同步块,这是第一重检查。进入同步块过后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,这是第二重检查。这样一来,就只需要同步一次了,从而减少了多次在同步情况下进行判断所浪费的时间。 

    双重检查加锁机制的实现会使用一个关键字volatile,它的意思是:被volatile修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量。

    5,静态内部类

    public class Singleton {

    private Singleton() {}

    private static class SingletonInstance {

    private static final Singleton INSTANCE = new Singleton();

    }

    public static Singleton getInstance() {

    return SingletonInstance.INSTANCE;

    }

    }

    这种方式跟饿汉式方式采用的机制类似,但又有不同。两者都是采用了类装载的机制来保证初始化实例时只有一个线程。不同的地方在饿汉式方式是只要Singleton类被装载就会实例化,没有Lazy-Loading的作用,而静态内部类方式在Singleton类被装载时并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SingletonInstance类,从而完成Singleton的实例化。

    类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。

    优点:避免了线程不安全,延迟加载,效率高。

    相关文章

      网友评论

          本文标题:移动开发-单例模式

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