单例模式5种写法

单例模式是设计模式中最简单的一种,其目的是确保一个类只有一个实例,并提供一个全局访问点。以下是单例模式的五种常见写法:

一、懒汉式(线程不安全)

```java

public class Singleton {

private static Singleton instance;

private Singleton() {}

public static Singleton getInstance() {

if (instance == null) {

instance = new Singleton();

}

return instance;

}

}

```

**原理**:

  • `instance`变量用于存储唯一的实例,初始值为`null`。

  • 构造方法`private`修饰,防止外部通过`new`关键字创建实例。

  • `getInstance()`方法用于获取实例。首次调用时,`instance`为`null`,会创建一个新实例并赋值给`instance`,之后再次调用`getInstance()`时,直接返回已创建的实例。

**缺点**:

  • 在多线程环境下,可能会出现多个线程同时进入`if (instance == null)`判断,导致创建多个实例。

二、懒汉式(线程安全,同步方法)

```java

public class Singleton {

private static Singleton instance;

private Singleton() {}

public static synchronized Singleton getInstance() {

if (instance == null) {

instance = new Singleton();

}

return instance;

}

}

```

**原理**:

  • 在`getInstance()`方法上加上`synchronized`关键字,使该方法在多线程环境下是线程安全的。

  • 当多个线程同时调用`getInstance()`时,只有一个线程能进入该方法,其他线程会等待当前线程执行完后再进入,从而保证了实例的唯一性。

**缺点**:

  • 使用`synchronized`修饰方法会导致性能下降,因为每次调用`getInstance()`方法都会进行同步,即使实例已经被创建。

三、懒汉式(线程安全,同步代码块)

```java

public class Singleton {

private static Singleton instance;

private Singleton() {}

public static Singleton getInstance() {

if (instance == null) {

synchronized (Singleton.class) {

if (instance == null) {

instance = new Singleton();

}

}

}

return instance;

}

}

```

**原理**:

  • 使用同步代码块代替同步方法,只对实例创建部分的代码进行同步。

  • 第一次检查`instance`是否为`null`,如果不为`null`,直接返回实例,避免了不必要的同步。

  • 如果`instance`为`null`,进入同步代码块,再次检查`instance`是否为`null`,如果仍为`null`,则创建实例。这称为双重检查锁定(Double - Check - Locking,DCL)。

**优点**:

  • 在保证线程安全的同时,提高了性能,因为只有在实例未被创建时才会进行同步。

四、饿汉式

```java

public class Singleton {

private static final Singleton instance = new Singleton();

private Singleton() {}

public static Singleton getInstance() {

return instance;

}

}

```

**原理**:

  • 在类加载时就创建实例,`instance`变量被`final`修饰,保证了其不可变性。

  • 构造方法`private`修饰,防止外部创建实例。

  • `getInstance()`方法直接返回已创建的实例。

**优点**:

  • 实现简单,线程安全,因为类加载是线程安全的,所以实例的创建也是线程安全的。

**缺点**:

  • 缺乏懒加载特性,不管是否使用该实例,都会在类加载时创建,可能会造成不必要的资源浪费。

五、静态内部类

```java

public class Singleton {

private Singleton() {}

private static class SingletonHolder {

private static final Singleton INSTANCE = new Singleton();

}

public static Singleton getInstance() {

return SingletonHolder.INSTANCE;

}

}

```

**原理**:

  • 使用一个静态内部类`SingletonHolder`来持有单例实例。

  • 外部类的构造方法`private`修饰,防止外部创建实例。

  • `getInstance()`方法返回`SingletonHolder`类中的`INSTANCE`实例。

  • 静态内部类在第一次被使用时才会被加载,因此具有懒加载特性,且由于类加载是线程安全的,所以这种方式也是线程安全的。

**优点**:

  • 兼具懒加载和线程安全的优点,是单例模式的一种优雅实现方式。
相关推荐
一点多余.5 天前
java中的单例模式
java·开发语言·单例模式
NaCl鱼呜啦啦6 天前
static 实例 vs 单例模式
开发语言·单例模式
白太岁7 天前
C++:(5) 单例模式与支持初始化失败的单例模式
c++·单例模式
A懿轩A8 天前
【Java 基础编程】Java 面向对象进阶:static/final、抽象类、接口、单例模式
java·开发语言·单例模式
郝学胜-神的一滴8 天前
单例模式:从经典实现到Vibe Coding时代的思考
开发语言·c++·程序人生·单例模式·设计模式·多线程
Andy Dennis9 天前
各种单例模式的实现方式
java·单例模式
逆境不可逃9 天前
【从零入门23种设计模式02】创建型之单例模式(5种实现形式)
java·spring boot·后端·单例模式·设计模式·职场和发展
百锦再11 天前
线程安全的单例模式全方位解读:从原理到最佳实践
java·javascript·安全·spring·单例模式·kafka·tomcat
柴郡猫乐园14 天前
JDK中一个单例模式的实现
java·开发语言·单例模式
HEU_firejef14 天前
设计模式——单例模式
单例模式·设计模式