首页 > 学院 > 开发设计 > 正文

【面试题2】实现Singleton模式

2019-11-06 08:23:12
字体:
来源:转载
供稿:网友

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

只能生成一个实例的类是实现了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。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表