单例模式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`实例。

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

**优点**:

  • 兼具懒加载和线程安全的优点,是单例模式的一种优雅实现方式。
相关推荐
狂奔的sherry11 小时前
单例模式(巨通俗易懂)普通单例,懒汉单例的实现和区别,依赖注入......
开发语言·c++·单例模式
晨星05272 天前
软件设计模式之单例模式
单例模式·设计模式
code bean4 天前
【wpf】WPF开发避坑指南:单例模式中依赖注入导致XAML设计器崩溃的解决方案
单例模式·wpf
是三好5 天前
单例模式(Singleton Pattern)
java·开发语言·算法·单例模式
青春易逝丶5 天前
单例模式
单例模式
YA3335 天前
java设计模式一、单例模式
java·单例模式·设计模式
枫景Maple6 天前
Unity中多线程与高并发下的单例模式
unity·单例模式·游戏引擎
iiiiaaiashah6 天前
单例模式的mock类注入单元测试与友元类解决方案
java·开发语言·单例模式
jingfeng51410 天前
线程池及线程池单例模式
linux·开发语言·单例模式
Brookty10 天前
深入解析Java并发编程与单例模式
java·开发语言·学习·单例模式·java-ee