一 设计模式创建型模式( 五 )


实现
我们将创建一个类 。类有它的私有构造函数和本身的一个静态实例 。
类提供了一个静态方法,供外界获取它的静态实例 。,我们的演示类使用类来获取对象 。
步骤 1
创建一个类 。
public class SingleObject {//创建 SingleObject 的一个对象private static SingleObject instance = new SingleObject();//让构造函数为 private,这样该类就不会被实例化private SingleObject(){}//获取唯一可用的对象public static SingleObject getInstance(){return instance;}public void showMessage(){System.out.println("Hello World!");}}
步骤 2
从类获取唯一的对象 。
public class SingletonPatternDemo {public static void main(String[] args) {//不合法的构造函数//编译时错误:构造函数 SingleObject() 是不可见的//SingleObject object = new SingleObject();//获取唯一可用的对象SingleObject object = SingleObject.getInstance();//显示消息object.showMessage();}}
步骤 3
执行程序,输出结果:
Hello World!
单例模式的几种实现方式
单例模式的实现有多种方式,如下所示:
1、懒汉式,线程不安全
是否 Lazy 初始化:是
是否多线程安全:否
实现难度:易
描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程 。因为没有加锁 ,所以严格意义上它并不算单例模式 。
这种方式 lazy很明显,不要求线程安全,在多线程不能正常工作 。
实例
public class Singleton {private static Singleton instance;private Singleton (){}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}}
接下来介绍的几种实现方式都支持多线程,但是在性能上有所差异 。
2、懒汉式,线程安全
是否 Lazy 初始化:是
是否多线程安全:是
实现难度:易
描述:这种方式具备很好的 lazy ,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步 。
优点:第一次调用才初始化,避免内存浪费 。
缺点:必须加锁才能保证单例,但加锁会影响效率 。
() 的性能对应用程序不是很关键(该方法使用不太频繁) 。
实例
public class Singleton {private static Singleton instance;private Singleton (){}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}}
3、饿汉式
是否 Lazy 初始化:否
是否多线程安全:是
实现难度:易
描述:这种方式比较常用,但容易产生垃圾对象 。
优点:没有加锁,执行效率会提高 。
缺点:类加载时就初始化,浪费内存 。
它基于机制避免了多线程的同步问题,不过, 在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化显然没有达到 lazy的效果 。
实例
public class Singleton {private static Singleton instance = new Singleton();private Singleton (){}public static Singleton getInstance() {return instance;}}
4、双检锁/双重校验锁(DCL,即 - )
JDK 版本:JDK1.5 起
是否 Lazy 初始化:是
是否多线程安全:是
实现难度:较复杂
描述:这种方式采用双锁机制,安全且在多线程情况下能保持高性能 。