Java设计模式之单例模式(Singleton Pattern)

来源:互联网 发布:正规网络兼职赚钱 编辑:程序博客网 时间:2024/06/05 14:20

对于设计模式,我们该如何了解,我想这不是一两句话就能说明白的。我也只是比较浅显地认识了一下,从我的角度出发,设计模式就是解决某一种问题的一种思想,是一种行之有效的解决方式。Java中共有23种设计模式,本文我就来讲解一下单例设计模式。

解决的问题

任何一种设计模式的出现,都是为了解决某一种问题的。单例设计模式也不例外,它的出现是为了保证一个类的对象在内存中的唯一性

应用场景

系统/应用只需要一个实例对象,确保对象的唯一性。

用例学习

在这里,我就举个例子来说明单例设计模式的应用场景。例如,多个程序都在操作同一个配置文件时,需要程序A操作后的结果,程序B要知道并继续基于程序A操作后的结果进行操作。如此一来就要有一个前提——数据都存储在配置文件对象中,要求程序A和程序B操作的配置文件对象是同一个。怎么才能解决这个案例呢?即怎么可以保证这个类只能产生一个对象呢?对此,我的分析思路是:

  1. 首先,问题是其他程序都可以通过new创建该类的对象,从而无法控制数量。所以,我们不让其他程序new不就可以了吗?
  2. 那么第一步的问题也产生了——其他程序不就没有对象了吗?干脆,在本类中自己new一个本类对象,这样的好处就是不让别的程序new,自己new,从而可以实现数量控制。
  3. 对外提供让其他程序获取该对象的方式,就可以了!

这样,解决步骤就呼之欲出了。

  1. 不让其他程序new该类对象,咋办?——可以将类中的构造函数私有化。
  2. 在本类中new一个对象。
  3. 定义一个方法返回该对象,让其他程序可以获取到。之所以定义方法访问,就是为了可控。

用代码体现出来就是:

public class Single{    // 创建一个本类对象    private static final Single s = new Single();    // 构造函数私有化    private Single(){}    // 定义一个方法返回该对象,让其他程序可以获取到。之所以定义方法访问,就是为了可控    public static Single getInstance()    {        return s;    }}

以上我们一般称之为饿汉式单例模式,单例模式有两种不同的实现方式,下面是懒汉式单例模式(也可称之为延迟加载方式)的代码体现。

public class Single{    // 创建一个本类对象    private static /*final*/ Single s = null; // 别加final,死!    // 构造函数私有化    private Single(){}    // 定义一个方法返回该对象,让其他程序可以获取到。之所以定义方法访问,就是为了可控    public static Single getInstance()    {        if (s == null)            s = new Single();        return s;    }}

上面代码还有一些瑕疵,因为在多线程并发访问时,会出现线程安全问题。加了同步就可以解决问题,无论是同步函数,还是同步代码块都行。但是效率低了,怎么解决效率低的问题呢?可以通过if对单例对象的双重判断的形式来解决。

public class Single {    private static Single s = null;    private Single() {}    public static Single getInstance() {        if(s == null) {            synchronized(Single.class) {                if(s == null)                    s = new Single();            }        }        return s;    }}

面试时,可能会问懒汉式与饿汉式有什么不同?答曰懒汉式的特点用于实例的延迟加载。又可能会接着问懒汉式的延迟加载有没有问题?答曰有,如果多线程访问时会出现安全问题。又问怎么解决呢?答曰可以加同步来解决,用同步代码块和同步函数都行,但是稍微有一些低效,用双重判断的形式能解决这个效率问题。最后可能会问加同步时,使用的锁是哪一个?答曰该类所属的字节码文件对象。