Java单例模式的6种实现方式详解

Java单例模式的6种实现方式详解

前言

单例模式是一种常见的设计模式,它可以保证一个类只有一个实例,并为外界提供唯一的访问入口。在实际开发中,单例模式经常被用于创建一些共享资源的场景,如数据库连接池、线程池等。本文将详细介绍Java中单例模式的六种实现方式。

1. 饿汉式(静态常量)

饿汉式单例模式的实现方式非常简单,就是在类加载的时候立即创建单例对象,因此也被称为静态常量方式。

public class Singleton {
    private static final Singleton INSTANCE = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() {
        return INSTANCE;
    }
}

使用场景:适用于单例对象较小,没有过多的资源占用的情况下。

示例:

public class Main {
    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); // 输出 true
    }
}

2. 饿汉式(静态代码块)

饿汉式单例模式的一种变种是静态代码块方式,它与静态常量方式的区别在于在静态代码块中可以进行一些初始化操作。

public class Singleton {
    private static final Singleton INSTANCE;
    static {
        INSTANCE = new Singleton();
        // 在这里进行初始化操作
    }
    private Singleton() {}
    public static Singleton getInstance() {
        return INSTANCE;
    }
}

使用场景:适用于单例对象需要进行一些初始化操作的情况下。

示例:

public class Main {
    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); // 输出 true
    }
}

3. 懒汉式(线程不安全)

懒汉式单例模式的实现方式是在第一次调用getInstance()方法时创建单例对象,如果同时有多个线程并发调用该方法,可能会创建多个实例,因此这种实现方式是线程不安全的。

public class Singleton {
    private static Singleton INSTANCE;
    private Singleton() {}
    public static Singleton getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }
}

使用场景:适用于单例对象较大,多线程情况比较少的情况下。

示例:

public class Main {
    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); // 输出 true
    }
}

4. 懒汉式(线程安全,同步方法)

为了解决线程安全问题,可以在getInstance()方法上添加synchronized关键字,保证多个线程调用该方法时只会创建一个单例对象,但是这种方式会降低并发性能。

public class Singleton {
    private static Singleton INSTANCE;
    private Singleton() {}
    public static synchronized Singleton getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }
}

使用场景:适用于单例对象较大,多线程情况比较多的情况下。

示例:

public class Main {
    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); // 输出 true
    }
}

5. 懒汉式(线程安全,双重校验锁)

双重校验锁是目前线程安全的懒汉式单例模式实现方式,它采用了同步代码块和synchronized关键字的结合使用,解决了线程安全和并发性能问题。

public class Singleton {
    private static volatile Singleton INSTANCE;
    private Singleton() {}
    public static Singleton getInstance() {
        if (INSTANCE == null) {
            synchronized (Singleton.class) {
                if (INSTANCE == null) {
                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }
}

使用场景:适用于单例对象较大,多线程情况比较多的情况下。

示例:

public class Main {
    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2); // 输出 true
    }
}

6. 枚举

枚举方式是目前最简单、最安全、最优雅的单例模式实现方式,它能够解决所有单例模式的问题,而且代码非常简洁明了。

public enum Singleton {
    INSTANCE;
    // 枚举类中的其他成员变量和成员方法
}

使用场景:适用于最简单、最安全、最优雅的单例模式实现方式。

示例:

public class Main {
    public static void main(String[] args) {
        Singleton instance1 = Singleton.INSTANCE;
        Singleton instance2 = Singleton.INSTANCE;
        System.out.println(instance1 == instance2); // 输出 true
    }
}

结语

以上就是Java中单例模式的六种实现方式,各有优缺点,需要根据具体情况选择。如果不要求延迟加载,可以选择饿汉式,否则应该选择懒汉式;如果需要保证线程安全,可以选择双重校验锁或枚举方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java单例模式的6种实现方式详解 - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • java实现时钟表盘

    下面我将详细讲解Java实现时钟表盘的完整攻略。 环境准备 首先需要确保你的电脑上已经安装了JDK环境,并且配置了相应的环境变量。然后你需要找到适合的Java集成开发环境,例如Eclipse、IntelliJ IDEA等,这里我们以Eclipse为例。 构建项目 打开Eclipse,选择”New” -> “Java Project”。 输入项目名称,点…

    Java 2023年6月1日
    00
  • Java实现创建运行时类的对象操作示例

    创建运行时类的对象是一个非常常见且必须的操作,下面我将为您提供实现此操作的详细攻略,包括Java中的示例代码。 1. 了解Class类 在 Java 语言中,每一个类都会对应一个 Class 类的实例,这个实例包含了有关该类的信息,我们可以通过这个实例对该类进行操作。因此,了解 Class 类是实现创建运行时类的对象的第一步。 我们可以使用以下三种方式来获取…

    Java 2023年5月26日
    00
  • 基于Springboot吞吐量优化解决方案

    基于Spring Boot的吞吐量优化解决方案可以通过以下步骤实现: 使用异步处理 在Spring Boot中,可以使用异步处理来提高吞吐量。异步处理可以将请求处理分配给不同的线程,从而提高应用程序的并发性能。以下是一个使用异步处理的示例: @RestController public class MyController { @Autowired priv…

    Java 2023年5月15日
    00
  • 解决Hibernate4执行save()或update()无效问题的方法

    下面是详细讲解“解决Hibernate4执行save()或update()无效问题的方法”的完整攻略。 问题描述 在使用Hibernate4的过程中,有时会出现执行save()或update()方法无效的问题。这个问题一般是由于Hibernate在执行持久化操作时,需要在事务中进行,但是开发者没有正确配置事务所导致的。下面给出解决这个问题的方法。 解决方法 …

    Java 2023年5月20日
    00
  • Java如何提供给第三方使用接口方法详解

    Java提供给第三方使用接口方法是指使用Java编写一个库,供其他开发者在自己的项目中使用,这个库就是接口。接口提供了一种标准化、规范化的编程方法,让编写代码变得更加高效和可维护。 下面是Java提供给第三方使用接口方法的详细攻略: 1.编写接口类: 接口是一种抽象的数据类型,它只有方法声明,没有方法体。接口用于定义某种功能的标准,而不关心这个功能的具体实现…

    Java 2023年5月26日
    00
  • Spring与Web整合实例

    针对“Spring与Web整合实例”的完整攻略,我将从以下几个方面进行详细讲解: 环境搭建 Spring与Web整合配置 示例展示 一、环境搭建 在进行Spring与Web整合的实例之前,需要先搭建好相应的环境,主要包括以下几个方面: JDK环境的安装与配置 Tomcat服务器的安装与配置 Maven工具的安装与配置 Spring框架与Spring MVC组…

    Java 2023年5月19日
    00
  • 你应该知道的这些Mybatis-Plus使用技巧(小结)

    你应该知道的这些Mybatis-Plus使用技巧(小结) Mybatis-Plus是一个Mybatis的增强工具,拓展了Mybatis的功能,使得开发者在编写数据库CRUD操作时更加方便和快捷。本文将介绍一些Mybatis-Plus的使用技巧。 1. 自动生成代码 Mybatis-Plus提供了一种快速生成Mapper、实体类、Service、Service…

    Java 2023年5月20日
    00
  • 常见的原子操作有哪些?

    常见的原子操作是指直接在硬件层面上实现的原子性操作。这些操作,在多线程并发的环境下非常有用,可以保证对数据的操作是完整和一致的。常见的原子操作包括实现加减操作和内存屏障操作。 实现加减操作 在 Python 中,有一个标准的模块 threading,提供了多线程编程所需要的相关方法和类。这个模块提供了 Lock() 锁的类,用于互斥访问共享资源。其中,RLo…

    Java 2023年5月10日
    00
合作推广
合作推广
分享本页
返回顶部