《Java设计模式及实践》—2 创建型模式
第2章
创建型模式
本章主要介绍了创建型模式(Creational Pattern)。创建型模式主要用于处理对象的创建问题,本章主要介绍以下内容:
单例模式
工厂模式
建造者模式
原型模式
对象池模式
2.1 单例模式
自Java语言推广使用以来,单例模式(singleton pattern)就是最常用的设计模式,它具有易于理解、使用简便等特点。有时单例模式会过度使用或在不合适的场景下使用,造成弊大于利的后果,因此,单例模式有时被认为是一种反模式。但是很多情况下单例模式是不可或缺的。
单例模式,顾名思义,用来保证一个对象只能创建一个实例,除此之外,它还提供了对实例的全局访问方法。单例模式的实现方式如图2-1所示。
图 2-1
单例模式的实现非常简单,只由单个类组成。为确保单例实例的唯一性,所有的单例构造器都要被声明为私有的(private),再通过声明静态(static)方法实现全局访问获得该单例实例。实现代码如下所示:
当我们在代码中使用单例对象时,只需进行简单的调用,代码如下所示:
在getInstance方法中,需要判断实例是否为空。如果实例不为空,则表示该对象在之前已被创建;否则,用新的构造器创建它。经过这些操作,无论是哪种情况,实例都不再为空,可以返回实例对象。
2.1.1 同步锁单例模式
单例模式的实现代码简单且高效,但还需注意一种特殊情况,在多线程应用中使用这种模式,如果实例为空,可能存在两个线程同时调用getInstance方法的情况。如果发生这种情况,第一个线程会首先使用新构造器实例化单例对象,同时第二个线程也会检查单例实例是否为空,由于第一个线程还没完成单例对象的实例化操作,所以第二个线程会发现这个实例是空的,也会开始实例化单例对象。
上述场景看似发生概率很小,但在实例化单例对象需要较长时间的情况下,发生的可能性就足够高,这种情况往往不能忽视。
要解决这个问题很简单,我们只需要创建一个代码块来检查实例是否空线程安全。可以通过以下两种方式来实现。
向getInstance方法的声明中添加synchronized关键字以保证其线程安全:
用synchronized代码块包装if (instance == null)条件。在这一环境中使用synch-ronized代码块时,需要指定一个对象来提供锁,Singleton.class对象就起这种作用。如以下代码片段所示:
- 点赞
- 收藏
- 关注作者
评论(0)