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 lambda循环_使用Java 8 Lambda简化嵌套循环操作

    下面是关于Java 8 Lambda简化嵌套循环操作的攻略: 1. lambda表达式简介 Java 8引入了lambda表达式,它是一种匿名函数,可以像参数一样传递给方法或赋值给变量。在使用lambda表达式时只需要关注其输入和输出,而不必关心具体的实现细节,这让代码变得更加简洁易读。 2. 简化循环操作 在Java 8之前,嵌套循环操作可能会使代码显得冗…

    Java 2023年5月26日
    00
  • java实现数字炸弹

    Java实现数字炸弹是一种常见的编程练习,主要是为了训练学生对于递归算法的理解和运用能力,以下是数字炸弹的完整攻略: 什么是数字炸弹? 数字炸弹指的是在一个数字序列中寻找出现次数最高的数字,并将出现次数最高的数字从序列中删除,接着重复以上步骤,直到序列为空。 怎样实现数字炸弹? 1. 将数字序列分解为数字数组 在Java中,我们可以将数字序列转化为数字数组,…

    Java 2023年5月23日
    00
  • java实现两个文件的异或运算

    实现两个文件的异或运算,可以通过以下几个步骤来完成: 读取文件内容。使用java提供的File类和FileInputStream类,用来读取文件内容。 进行异或操作,将两个字节数组对应位进行异或运算。 将异或结果写入输出文件中。使用java提供的FileOutputStream类,将异或结果写入输出文件中。 下面是一个示例代码,用来实现两个文件的异或运算: …

    Java 2023年5月19日
    00
  • 亲手带你解决Debug Fastjson的安全漏洞

    下面我将为你讲解如何解决Fastjson的安全漏洞。 什么是Fastjson的漏洞? Fastjson是一款被广泛使用的Java JSON解析器和生成器。然而,在Fastjson中存在一些安全漏洞,使得攻击者可以利用它来执行远程代码、绕过安全措施、拒绝服务攻击等。为了保护我们的应用程序免受这些漏洞的影响,我们需要及时采取措施来解决这些漏洞问题。 解决Fast…

    Java 2023年6月15日
    00
  • Java实现软件运行时启动信息窗口的方法

    首先需要解释一下题目,所谓软件运行时启动信息窗口,通常是指在程序启动的时候,弹出一个窗口展示程序的一些信息,比如版本号、作者信息、最新更新内容等。 Java实现软件运行时启动信息窗口,可以采用Swing框架提供的JOptionPane类。JOptionPane可以用于创建带有消息、警告、错误、询问等各种类型的对话框,并且可以自定义对话框的信息内容、按钮选项等…

    Java 2023年6月15日
    00
  • Java中的多种文件上传方式总结

    下面我将详细讲解“Java中的多种文件上传方式总结”的完整攻略。 Java中的多种文件上传方式总结 背景 在Web应用程序中,常常需要上传文件,例如上传图片、视频、文件等等。Java中有多种文件上传方式,下面将为大家总结这些方式及其优缺点。 方式一:使用Servlet 3.0提供的Part接口进行文件上传 在Servlet 3.0中,新增了Part接口,可以…

    Java 2023年5月20日
    00
  • Java钩子方法概念原理详解

    Java钩子方法概念原理详解 Java中的钩子方法(Hook Method),顾名思义就是在某个阶段插入一些代码,以改变程序的控制流程或增加一些新的功能,从而达到在运行时改变程序行为的目的。 钩子方法原理 我们知道Java中有很多基础的类和接口,比如Thread类、WindowAdapter类、Servlet类等等,在这些类和接口中一般会预留一些钩子方法,等…

    Java 2023年5月26日
    00
  • SpringBoot集成WebSocket实现前后端消息互传的方法

    下面是 SpringBoot 集成 WebSocket 实现前后端消息互传的完整攻略。 简介 WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket 使得浏览器和服务器之间的实时通信变得更加容易。Spring Boot 提供了一个强大的 WebSocket 模块,可以轻松实现 WebSocket 的集…

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