java单例五种实现模式解析

Java单例五种实现模式解析

什么是单例模式?

单例模式是指一个类只能被实例化一次,并且全局都可以访问到这个实例。在实际开发中,很多情况下我们只需要一个实例,例如全局配置信息、日志管理等等,这时候使用单例模式可以节省系统资源,减少不必要的开销。

单例模式的特点

  • 保证一个类只有一个实例。
  • 提供一个访问该实例的全局入口。
  • 不能被其他对象实例化。

五种实现模式

1. 饿汉式

线程安全

饿汉式在类被加载的同时就创建好了唯一的实例,故天然的线程安全。

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

示例说明

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 Singleton instance = null;
    private Singleton(){}
    public static Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

线程安全

使用双重判定锁的方式可以保证线程安全性。

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

示例说明

public static void main(String[] args) {
    Singleton instance1 = Singleton.getInstance();
    Singleton instance2 = Singleton.getInstance();
    System.out.println(instance1 == instance2);
}

输出结果为 true,表明两个实例指向同一内存空间,即单例模式被实现。

3. 静态内部类

这种方式利用了 Classloader 的机制来保证初始化实例时只有一个线程。静态内部类不会在类加载时就初始化,而是当被调用时才进行初始化。

public class Singleton {
    private Singleton(){}
    private static class SingletonHolder{
        private static final Singleton instance = new Singleton();
    }
    public static final Singleton getInstance(){
        return SingletonHolder.instance;
    }
}

示例说明

public static void main(String[] args) {
    Singleton instance1 = Singleton.getInstance();
    Singleton instance2 = Singleton.getInstance();
    System.out.println(instance1 == instance2);
}

输出结果为 true,表明两个实例指向同一内存空间,即单例模式被实现。

4. 枚举类型

枚举类型被限制了元素个数,保证了单例模式的实现,且避免了线程安全问题。

public enum Singleton {
    INSTANCE;
    public void whateverMethod() { }
}

示例说明

public static void main(String[] args) {
    Singleton instance1 = Singleton.INSTANCE;
    Singleton instance2 = Singleton.INSTANCE;
    System.out.println(instance1 == instance2);
}

输出结果为 true,表明两个实例指向同一内存空间,即单例模式被实现。

5. 双重校验锁

这种方式可以在保证线程安全的情况下实现懒加载。

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

示例说明

public static void main(String[] args) {
    Singleton instance1 = Singleton.getInstance();
    Singleton instance2 = Singleton.getInstance();
    System.out.println(instance1 == instance2);
}

输出结果为 true,表明两个实例指向同一内存空间,即单例模式被实现。

总结

以上五种单例实现方式各有优缺点,应根据具体情况选择。选用不合适的单例实现方式会导致系统资源浪费、性能降低及线程安全问题等。

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

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

相关文章

  • Java 将一个字符重复n遍过程详解

    当我们需要将一个字符重复n遍时,我们可以使用Java的String类提供的重复方法repeat()。 该方法接受一个参数n,表示需要将字符重复的次数,然后返回一个新的字符串,其中指定的字符被重复n次。下面是使用repeat()方法的基本语法: String repeatedString = "a".repeat(n); 该语句将创建一个由…

    Java 2023年5月27日
    00
  • 如何实现Java线程安全问题

    Java线程安全是一个非常重要的问题,它涉及到在多线程情况下对共享资源的访问和操作。如果不注意线程安全问题,可能会导致数据混乱、竞态条件等问题。下面是一些实现Java线程安全的攻略: 1.使用同步方法和同步块 同步方法和同步块都可以用来实现线程安全。它们的核心思想是在多个线程访问共享资源时,只有一个线程能够访问这个资源,其他线程需要等待。具体实现方式如下: …

    Java 2023年5月26日
    00
  • 搭建MyBatis-Plus框架并进行数据库增删改查功能

    搭建MyBatis-Plus框架并进行数据库增删改查功能的完整攻略如下: 准备工作 下载和安装JDK和MySQL; 创建一个Spring Boot项目; 在项目中添加mybatis-plus-boot-starter依赖; 在项目的配置文件中配置数据库连接信息。 配置MyBatis-Plus框架 创建数据库表; 创建实体类,并在类上添加@TableField…

    Java 2023年6月1日
    00
  • 详解Elastic Search搜索引擎在SpringBoot中的实践

    详解ElasticSearch搜索引擎在SpringBoot中的实践 ElasticSearch 是一个基于 Lucene 的搜索引擎,它提供了分布式、多租户、全文搜索等功能。在 Spring Boot 中,我们可以使用 Spring Data Elasticsearch 来集成 ElasticSearch,实现搜索功能。本文将详细介绍 ElasticSea…

    Java 2023年5月15日
    00
  • 如何将Java与C#时间进行互相转换

    让我详细讲解一下如何将Java与C#时间进行互相转换的完整攻略。 1. 时间格式的理解 Java与C#时间的存储方式是不同的,所以在互相转换之前需要先了解它们的时间格式。下面是Java与C#时间的时间格式: Java时间格式: yyyy-MM-dd HH:mm:ss C#时间格式: yyyy/MM/dd HH:mm:ss 其中 yyyy 表示年份,MM 表示…

    Java 2023年5月20日
    00
  • 关于Java实现HttpServer模拟前端接口调用

    关于Java实现HttpServer模拟前端接口调用,可以按照以下步骤进行: 一、实现HttpServer 1.引入HttpServer依赖,例如使用Jetty <dependencies> <dependency> <groupId>org.eclipse.jetty</groupId> <artifa…

    Java 2023年5月26日
    00
  • C#桥接模式完整实例

    C#桥接模式是一种软件设计模式,旨在将抽象和实现分离开来,以便它们可以独立地进行变化和演化。在此模式下,一个抽象类在其内部维护一个实现类的引用,并将具体的实现委托给实现类。这样便可以在不改变抽象类结构的情况下,改变具体实现类。 下面我们采用一个“图形和颜色”系统作为示例,在这个系统中,“图形”和“颜色”是两个独立的概念,它们可以独立从抽象和实现上进行扩展,并…

    Java 2023年5月19日
    00
  • SpringSecurity页面授权与登录验证实现(内存取值与数据库取值)

    下面我将详细讲解“SpringSecurity页面授权与登录验证实现(内存取值与数据库取值)”的完整攻略。 一、概述 在开发Web应用程序时,安全性一直是非常重要的一环。Spring Security是Spring Framework所提供的一个强大的安全性框架,能够帮助我们很容易实现认证和授权功能。本文将介绍SpringSecurity页面授权与登录验证实…

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