Java中单例模式的七种写法示例

Java中单例模式的七种写法示例

什么是单例模式?

单例模式是一种创建型设计模式,它保证某个类在应用程序中只有一个对象实例存在。

在应用程序中,有些实例对象需要全局唯一,比如数据库连接实例、日志记录实例等,此时就可以使用单例模式来确保只创建一个对象实例,以达到节约系统资源的目的。

单例模式的七种实现方式

1. 饿汉式单例模式

public class Singleton1{
    private static Singleton1 instance = new Singleton1();
    private Singleton1(){}

    public static Singleton1 getInstance() {
        return instance;
    }
}

在类加载时,就创建了静态的实例对象,保障了在多线程环境下也能保证唯一的实例对象。

此方式的缺点是:在应用程序启动时,就创建了实例对象,占用了一部分JVM内存,如果这个对象无法在应用程序启动后被调用,就浪费了系统资源,且不能实现懒加载,需要时间和空间上的代价。

2. 懒汉式单例模式(线程不安全)

public class Singleton2{
    private static Singleton2 instance;
    private Singleton2(){}

    public static Singleton2 getInstance() {
        if(instance == null) {
            instance = new Singleton2();
        }
        return instance;
    }
}

此方式是懒汉式的单例模式,只有在调用该方法时才会创建并返回实例对象,但是,在多线程环境下,可能会出现多个实例对象的情况。

3. 懒汉式单例模式(线程安全,效率低)

public class Singleton3{
    private static Singleton3 instance;
    private Singleton3(){}

    public static synchronized Singleton3 getInstance() {
        if(instance == null) {
            instance = new Singleton3();
        }
        return instance;
    }
}

考虑到线程安全问题,该方法添加了synchronized关键字,保证只有一个线程可以访问创建实例对象的过程,保证线程安全。但是,由于该方法在整个过程中只有一个线程可以执行,因此会带来效率低下的问题。

4. 双重检查锁单例模式(线程安全)

public class Singleton4{
    private volatile static Singleton4 instance;
    private Singleton4(){}

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

该方法对懒汉式方法进行了优化,利用双重检查锁定机制,在多线程环境下保证只创建唯一的实例对象、线程安全,同时,在实例对象创建完成后,其他线程可以直接访问实例对象。 使用volatile关键字可以保证线程间变量的可见性,从而保证线程安全。

5. 静态内部类单例模式

public class Singleton5{
    private Singleton5(){}

    private static class SingletonHolder{
        private static final Singleton5 INSTANCE = new Singleton5();
    }

    public static Singleton5 getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

采用静态内部类的方式,保证实例对象唯一,线程安全,同时具有懒加载的優點。

6. 枚举写法单例模式

public enum Singleton6 {
    INSTANCE;

    public static Singleton6 getInstance() {
        return INSTANCE;
    }
}

JDK1.5开始支持枚举类型。这种方式在多线程环境下也可以保证实例对象唯一、线程安全,并且可以防止反射机制和反序列化攻击。

7. ThreadLocal单例模式

public class Singleton7{
    private static final ThreadLocal<Singleton7> threadLocalInstance = new ThreadLocal<Singleton7>() {
        @Override
        protected Singleton7 initialValue() {
            return new Singleton7();
        }
    };

    private Singleton7(){}

    public static Singleton7 getInstance() {
        return threadLocalInstance.get();
    }
}

采用ThreadLocal的方式,保证单例对象的唯一性,在多线程环境下也能够保证线程安全。

小结

以上是Java中七种单例模式的实现方式,每种方式都可以应对不同情况下的开发需求。在实际应用中,可以选择最适合自己需求的方式进行使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中单例模式的七种写法示例 - Python技术站

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

相关文章

  • sourceTree合并一次提交的内容

    sourceTree合并一次提交的内容 在基于git的开发中,经常遇到不同分支需要合并某一次特定的提交的代码,而不是合并整个代码。 场景:A分支是通用分支,B分支是私有化分支,现在A分支修改了一个通用的功能,需要合并到B分支上,功能在一次提交上。B分支只需要这次提交的代码,对A分支上改动的其他代码都不感兴趣。对此,常规的merge已经不能满足我们的需求。 1…

    Java 2023年4月27日
    00
  • JAVA实现往字符串中某位置加入一个字符串

    现在我会详细讲解如何在Java中实现往字符串中某位置加入一个字符串的完整攻略。下面是具体步骤: 1. 创建一个StringBuilder对象 在Java中,比起直接使用String类,我们更推荐使用StringBuilder类来进行字符串拼接。因为每次对一个String对象进行字符串拼接时,都会创建一个新的String对象,这样就会浪费很多内存空间。 Str…

    Java 2023年5月26日
    00
  • Java读取文件的简单实现方法

    下面我会详细讲解“Java读取文件的简单实现方法”的完整攻略。 什么是Java读取文件? Java读取文件是指通过Java程序去读取本地或服务器上的文件,可以实现从文件中获取数据、修改数据等功能。在Java中,可以使用多种方法来读取文件,比如使用字节流或字符流等。 如何使用Java读取文件? 使用字节流读取文件 字节流可以读取任何类型的文件,比如文本文件、图…

    Java 2023年5月19日
    00
  • gateway、webflux、reactor-netty请求日志输出方式

    为了让大家更好地了解 “gateway、webflux、reactor-netty请求日志输出方式”,我将分别讲解这三个主题,并提供相应的示例代码,在此之前,请确保已经安装好了Java环境,并了解基本的Spring Boot框架。 Gateway请求日志输出方式 Gateway是Spring Cloud的组件之一,可以将多个微服务组合起来作为一个整体对外提供…

    Java 2023年5月20日
    00
  • 详解DES加密算法及在Java程序中的使用示例

    详解DES加密算法及在Java程序中的使用示例 简介 DES(Data Encryption Standard)算法是一种基于对称密钥加密的算法,是保护计算机数据最常用的方法之一。该算法使用相同的密钥进行加密和解密,主要用于保护敏感数据的安全性。本文将详细讲解DES加密算法,并提供它在Java程序中的使用示例。 DES加密算法 DES算法主要包括两个过程:加…

    Java 2023年5月26日
    00
  • java使用jdbc连接数据库简单实例

    Java使用JDBC连接数据库简单实例 在Java中,我们通过JDBC(Java Database Connectivity) API来连接数据库。这里简单介绍一下如何使用JDBC连接数据库。 步骤 下载并安装数据库驱动程序。不同的数据库具有不同的驱动程序,请根据实际情况选择。 加载驱动程序,可以通过Class.forName()方法进行加载 java Cl…

    Java 2023年5月19日
    00
  • SpringBoot启动失败的解决方法:A component required a bean of type ‘xxxxxxx‘ that could not be found.

    当我们在使用SpringBoot构建应用时,有时候在启动应用的时候会遇到如下错误提示: *************************** APPLICATION FAILED TO START *************************** Description: A component required a bean of type ‘xx…

    Java 2023年6月2日
    00
  • Java8新特性之Base64详解_动力节点Java学院整理

    Java8新特性之Base64详解 介绍 Base64是用来将二进制数据编码为可打印ASCII字符的一种方法。Java8在java.util下新增了Base64类,提供了Base64编解码的实现。 Base64的编码与解码 Base64可以将任意二进制数据编码为ASCII字符,编码后的长度会比原始数据大1/3。编码方式如下: 将要编码的数据划分成每6个比特为…

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