面试突击50:单例模式有几种写法?

简介: Java常见面试题系列文章

单例模式是面试中的常客了,它的常见写法有 4 种:饿汉模式、懒汉模式、静态内部类和枚举,接下来我们一一来看。

## 1.饿汉模式

饿汉模式也叫预加载模式,它是在类加载时直接创建并初始化单例对象,所以它并不存在线程安全的问题。它是依靠 ClassLoader 类机制,在程序启动时只加载一次,因此不存在线程安全问题,它的实现代码如下:

```java

public class Singleton {

   // 1.防止外部直接 new 对象破坏单例模式

   private Singleton() {}

   // 2.通过私有变量保存单例对象

   private static Singleton instance = new Singleton();

   // 3.提供公共获取单例对象的方法

   public static Singleton getInstance() {

       return instance;

   }

}

```

**优点**:实现简单、不存在线程安全问题。

**缺点**:类加载时就创建了对象,创建之后如果没被使用,就造成了资源浪费的情况。

## 2.懒汉模式

懒汉模式和饿汉模式正好是相反的,所谓的懒汉模式也就是懒加载(延迟加载),指的是它只有在第一次被使用时,才会被初始化,它的实现代码如下:

```java

public class Singleton {

   // 1.防止外部直接 new 对象破坏单例模式

   private Singleton() {}

   // 2.通过私有变量保存单例对象

   private static volatile Singleton instance = null;

   // 3.提供公共获取单例对象的方法

   public static Singleton getInstance() {

       if (instance == null) { // 第一次效验

           synchronized (Singleton.class) {

               if (instance == null) { // 第二次效验

                   instance = new Singleton();

               }

           }

       }

       return instance;

   }

}

```

**懒汉模式使用的是双重效验锁和 volatile 来保证线程安全的**,从上述代码可以看出,无论是饿汉模式还是懒汉模式,它们的实现步骤都是一样的:

1. 创建一个私有的构造方法,防止其他调用的地方直接 new 对象,这样创建出来的对象就不是单例对象了。

2. 创建一个私有变量来保存单例对象。

3. 提供一个公共的方法返回单例对象。

懒汉模式相比于饿汉模式来说,不会造成资源的浪费,但写法要复杂一些。

## 3.静态内部类

**静态内部类既能保证线程安全,又能保证懒加载**,它只有在被调用时,才会通过 ClassLoader 机制来加载和初始化内部静态类,因此它是线程安全的,此模式的实现代码如下:

```java

public class Singleton {

   // 1.防止外部直接 new 对象破坏单例模式

   private Singleton() {

   }

   // 2.静态内部类

   private static class SingletonHolder {

       private static final Singleton INSTANCE = new Singleton();

   }

   // 3.提供公共获取单例对象的方法

   public static final Singleton getInstance() {

       return SingletonHolder.INSTANCE;

   }

}

```

## 4.枚举

**枚举也是在第一次被使用时,才会被 Java 虚拟机加载并初始化,所以它也是线程安全的,且是懒加载的**,它的实现代码如下:

```java

public enum  EnumSingleton {

   INSTANCE;

   public EnumSingleton getInstance(){

       return INSTANCE;

   }

}

```

## 总结

单例模式适用于经常被访问的对象,或是创建和销毁需要调用大量资源和时间的对象,使用单例模式可以避免频繁创建和销毁对象。单例模式的常用实现方法有 4 种:饿汉模式、懒汉模式、静态内部类和枚举。从写法的简洁性、线程安全性和代码的易懂性等方面综合来看,博主比较推荐使用枚举或懒汉模式来实现单例模式。

> 是非审之于己,毁誉听之于人,得失安之于数。

>  

> 公众号:Java面试真题解析

>  

> 面试合集:[https://gitee.com/mydb/interview](https://gitee.com/mydb/interview)

相关文章
|
1月前
|
机器学习/深度学习 算法 搜索推荐
|
1月前
|
设计模式 安全 Java
Java线程面试题:如何在 Java 中实现线程安全的单例模式?
Java线程面试题:如何在 Java 中实现线程安全的单例模式?
31 0
|
7月前
|
设计模式 安全 Java
面试~设计模式---单例模式
面试~设计模式---单例模式
36 0
|
8月前
|
设计模式 存储 安全
面试易考:多线程模式下的单例模式两种具体实现(饿汉,懒汉),两个的线程安全性,阻塞队列,生产者消费者模型
面试易考:多线程模式下的单例模式两种具体实现(饿汉,懒汉),两个的线程安全性,阻塞队列,生产者消费者模型
|
11月前
|
设计模式 安全
面试最常见的设计模式之单例模式
面试最常见的设计模式之单例模式
91 1
|
12月前
|
设计模式 安全 调度
设计模式——单例模式(面试手撕顶呱呱)
设计模式——单例模式(面试手撕顶呱呱)
|
设计模式
【面试常问】说一下你对单例模式的理解
设计模式在开发中是重中之重,尤其是单例模式,因此也就成了面试中的高频问题,决定整理一下;如有错误还请个位指正!
58 0
|
安全 Java 编译器
JAVA面试官:请说说如何设计线程安全的单例模式?
JAVA面试官:请说说如何设计线程安全的单例模式?
|
设计模式 Java
面试基础篇——单例模式(二)
面试基础篇——单例模式
71 0
|
设计模式 安全 Java
面试基础篇——单例模式(一)
面试基础篇——单例模式
79 0