【面试题2】实现Singleton模式

题目:设计一个类,我们只能生成该类的一个实例。

只能生成一个实例的类是实现了Singleton(单例)模式的类型。由于设计模式在面向对象程序设计中起着举足轻重的作用,在面试过程中很多公司都喜欢问一些与设计模式相关的问题。在常用的设计模式中,Singleton是唯一一个能够用短短几十行代码完整实现的模式。因此,写一个Singleton的类型是一个很常见的面试题。


一、最简单的方式

public static Singleton getInstance() {
    if (instance == null) {
      instance = new Singleton();
    } 
    return instance;
  }
这是最简单的方式。该方式适合于单线程运行,如果在多线程环境下,需要对该方法进行同步。由此引出第二个方法。
二、线程同步的方法
public static synchronized Singleton getInstance() {
  if (instance == null) {
    instance = new Singleton();
  }
  return instance;
}
该方法可以在多线程环境下运行。但是由于在每次调用时都需要进行同步,因此消耗了一定的代价。因为只需要
在第一次创建实例时需要进行同步,其他情况下是不必须的。由此引出第三个方法。

三、改进的线程同步的方法
public static Singleton getInstance() {
  if (instance == null) {
    synchronized(Singleton.class) {
      instance = new Singleton();
    }
  }
  return instance;
}
该方法只需要在第一次创建实例时进行同步,减少了系统的开销。但是,当第二个线程进入synchronized同步块时,
没有检查实例是否为空,会存在线程安全问题。由此引出第四个方法,即双重检查锁定方法。
四、双重检查锁定方法
public static Singleton getInstance() {
  if (instance == null) {
    synchronized(Singleton.class) {
      if (instance == null) {
        instance = new Singleton();
      }
    }
  }
  return instance;
}

该方法减少了线程同步引起的开销,同时不存在线程安全问题。根据Java的内存模型,应该将instance引用类型
声明为volatile,该双重检查锁定方法可以正常运行。
五、饿汉式方法

public class Singleton

private static Singleton instance = new Singleton();

private Singleton(){}

public static Singleton getInstance() {

return instance;

}

}

当类被加载时,静态变量instance会被初始化,此时类的私有构造函数会被调用,单例类的唯一实例将被创建。可确保

单例对象的唯一性。关于Java类的构造函数执行顺序,请参考另一篇文章《Java构造函数》。该方法的优点在于

无须考虑多线程访问问题,可以确保实例的唯一性。但是,由于在类被加载时就创建了类对象,无论该类是否会被使用,

都占用系统内存。

六、IoDH技术

IoDH,即Initializationon on Demand Holder的缩写。IoDH技术单例类中增加一个静态(static)内部类,在该内部类中创建

单例对象,再将该单例对象通过getInstance()方法返回给外部使用。

public class Singleton {
    private  Singleton() {
    }
    private static class HolderClass {
        private final static Singleton  instance = new Singleton();
    }

    public static Singleton getInstance() {
        return HolderClass.instance;
    }
}

通过使用IoDH,既可以实现延迟加载,又可以保证线程安全,不影响系统性能,是一种最好的Java语言单例模式实现方式。

其缺点是与编程语言本身的特性相关,很多面向对象语言不支持IoDH。

















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值