什么是单例模式?
什么是单例模式呢? 我们引用一下维基百科:
单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。还有就是我们经常使用的servlet就是单例多线程的。使用单例能够节省很多内存。
如何实现单例模式呢?
我们引用一下维基百科: 实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。
好了,我们知道了单例模式的定义和如何使用单例的描述,接下来,就引用Linux Torvalds 的话:Talk is cheap. Show me the code!
下面我们看下单例模式实现的7中方式:
一、懒汉加载式:懒汉加载式,最简单的一种方式,分两步:1、把自己的构造设置为私有的,不让别人去访问你的实例;2、提供一个static方法给别人获取你的实例;
懒汉式加载版本单例模式:
我们可以看到,这是一个简单的获取单例的一个类,首先我们定义一个静态实例 single, 如何将构造方法变成私有的。并且给外界一个静态获取实例的方法。如果对象不是null,就直接返回实例,从而保证实例。也可以保证不浪费内存。这是我们的第一个实现单例模式的例子。很简单。但是有问题,我们后面再讲。
第二种:饥汉加载式
饿汉式加载版本单例模式:
我们看到第二种单例模式,代码量比第一个少了很多,而为什么叫饿汉式呢?我们看代码,我们定义了一个静态的final的实例,并且直接new了一个对象,这样就会导致Single2 类在加载字节码到虚拟机的时候就会实例化这个实例,当你调用getInstance方法的时候,就会直接返回,不必做任何判断,这样做的好处是代码量明显减少了,坏处是,在你没有使用该单例的时候,该单例却被加载了,如果该单例很大的话,将会浪费很多的内存。
我们停下来思考一下:
我们如何选择这两种实现方式呢?如果你的项目对性能没有要求,那么请直接使用饿汉式方法实现单例模式,既简单又方便。但是,大部分程序员都是有追求的,岂能不追求性能。那么我们看第一种方式,就是懒汉式,我们刚刚说过,懒汉式既保证了单例,又保证了性能。但是,他真的能保证单例吗?可以确定的是:在单线程模式下,毫无问题,但在复杂的多线程模式下,会怎么样呢?show me code .