软件设计模式与体系结构--单例模式

单例模式实例

饿汉模式和懒汉模式区别

一.懒汉模式
只有在自身需要的时候才会行动,从来不知道及早做好准备,它在需要对象的时候,才判断是否已有对象,如果没有就立即创建一个对象,然后返回,如果已有对象就不再创建,立即返回。懒汉模式只在外部对象第一次请求实例的时候才去创建。代码如下:
1>不加锁情况
软件设计模式与体系结构--单例模式_第1张图片
2>加锁情况
软件设计模式与体系结构--单例模式_第2张图片

加锁的原因

一般情况不加锁并没有任何问题,但是在多线程并发执行的时候就很容易出现问题,第一个线程在判断newInstance==null时,还没有new出实例时,第二个线程也进来,判断的newInstance也是null,然后也会new出实例,这就不是我们想要的单例模式了,所以就需要加锁,使用synchronized关键字.

两者区别

懒汉模式:在类加载的时候不被初始化。
饿汉模式:在类加载时就完成了初始化,但是加载比较慢,获取对象比较快。
饿汉模式是线程安全的,在类创建好一个静态对象提供给系统使用,懒汉模式在创建对象时不加上synchronized,会导致对象的访问不是线程安全的

二.饿汉模式
从名字去理解,它很饿,所以在加载类的时候,就进行初始化了。当你调用的时候,直接调用就好了。
代码如下:
软件设计模式与体系结构--单例模式_第3张图片

访问网站,百度算不算是单例模式

单例模式定义是保证一个类仅有一个实例,并提供一个访问它的全局访问点。
而访问网站,百度,可以同时通过多个地方登陆或者进入,它们的访问点有多个,所以不是单例模式。

loDH方式/或者技术 实现单例模式

饿汉式单例类不能实现延迟加载,不管将来用不用始终占据内存;懒汉式单例类线程安全控制烦琐,而且性能受影响。可见,无论是饿汉式单例还是懒汉式单例都存在这样那样的问题,有没有一种方法,能够将两种单例的缺点都克服,而将两者的优点合二为一呢?答案是:Yes!下面我们来学习这种更好的被称之为Initialization Demand Holder (IoDH)的技术。

在IoDH中,我们在单例类中增加一个静态(static)内部类,在该内部类中创建单例对象,再将该单例对象通过getInstance()方法返回给外部使用,实现代码如下所示:
软件设计模式与体系结构--单例模式_第4张图片
编译并运行上述代码,运行结果为:true,即创建的单例对象s1和s2为同一对象。由于静态单例对象没有作为Singleton的成员变量直接实例化,因此类加载时不会实例化Singleton,第一次调用getInstance()时将加载内部类HolderClass,在该内部类中定义了一个static类型的变量instance,此时会首先初始化这个成员变量,由Java虚拟机来保证其线程安全性,确保该成员变量只能初始化一次。由于getInstance()方法没有任何线程锁定,因此其性能不会造成任何影响。

通过使用IoDH,我们既可以实现延迟加载,又可以保证线程安全,不影响系统性能,不失为一种最好的Java语言单例模式实现方式(其缺点是与编程语言本身的特性相关,很多面向对象语言不支持IoDH)。

你可能感兴趣的:(软件设计模式与体系结构--单例模式)