单例模式详解,flutter 跳转
(3)确保单例对象只有一个(考虑多线程情况下)。
有时候在实现单例模式的时候,除了以上三点有时候我们还要防止反射破坏单例,反序列化的时候也会重新构建对象的实例。多进程的环境下,单例模式会失效,因为不同的进程运行在不同的虚拟机中,内存是不一样的。
下面我们来介绍常见的单例模式的写法
1.饿汉式单例模式
上面这两种都是饿汉式单例的写法,为什么说是饿汉式呢。因为上面两种写法,Manager 的实例,都是在 Manager 这个类被初? ? ?始化的时候,就被创建好了。这种写法,在多线程的环境下,也能保证只有一个对象被创建。缺点呢就是如果不使用的话,就会白白创建这个单例对象。造成浪费。
2.懒汉式单例
上面这种单例模式,就是懒汉式的实现方法,我们可以看到在 getInstance()方法上我们加上了 synchronized 的关键字。
这样我们就可以在多线程的环境下
,也只会生成一个对象的实例。但是上面这种写法有个很明显的缺点,就是我们的 synchronized 实现的是类锁,在我们第一次初始化成功之后,以后每次通过 getInstance()方法获取对象的实例时,都要先获取
当前类的类锁,在执行完方法后,还要释放锁,造成了资源的不必要的浪费。synchronized 操作是一个重量的操作,我们应当尽量避免这种操作。下面我们在来介绍一种懒汉式单例的写法 ,Double Check Log 实现单例。
DCL 实现的单例可以有效的避免我们上面的第一种懒汉式写法所造成的每次调用 getInstance()都要去获取类锁,执行完释放锁的操作。第一次初始化之后,我们调用该方法,发现对象已经实例化,直接返回当前已经实例化的对象。不会在走下面的同步操作。volatile 关键字起到的作用是禁止指令重排序。避免多线程同时在获取 manger 对象时,由于指令重排序,导致其他线程在获取 manger 对象的时候,manger 对象虽然不为 null,但还没有初始化。
3.静态内部类实例单例模式
评论