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日

相关文章

  • asp.net内置对象 Response对象使用介绍

    ASP.NET是一个基于.NET Framework的Web应用程序开发框架。在ASP.NET的开发过程中,Response对象是一个非常重要的内置对象,它提供了很多方法和属性来管理HTTP响应。本文将介绍如何利用Response对象来控制HTTP响应的内容和属性。 Response对象的作用 在ASP.NET的Web应用程序中,Response对象用于向客…

    Java 2023年5月19日
    00
  • java对象的序列化和反序列化

    下面是Java对象的序列化和反序列化的完整攻略: 概述 Java对象的序列化和反序列化是一种将对象转化成字节序列以便存储和传输的机制,同时也是将字节序列转化为对象的一种机制。 Java序列化通常用于将对象存储到文件中或者通过网络传输数据,反序列化则是将序列化后的字节流转换成原来的对象。 如何序列化和反序列化对象 Java对象的序列化和反序列化可以通过Java…

    Java 2023年5月26日
    00
  • SpringBoot中如何启动Tomcat流程

    SpringBoot是现在Java开发中比较热门的框架之一,它以快速启动、无代码生产和简洁的配置等优势著称。Tomcat是其中最常见的Web容器之一,本文将详细讲解在SpringBoot中如何启动Tomcat的流程。 1. SpringBoot启动Tomcat的流程 SpringBoot启动Tomcat的流程步骤如下: SpringBoot启动器根据项目中引…

    Java 2023年6月2日
    00
  • Java中字符串与byte数组之间的相互转换

    Java中字符串与byte数组之间的相互转换是经常使用的操作,下面是完整攻略: 字符串转byte数组 将字符串转换为byte数组可以通过以下两种方式实现: 1.使用String类的getBytes()方法 String str = "hello, world!"; byte[] bytes = str.getBytes(); 这里的get…

    Java 2023年5月26日
    00
  • Java栈的三种实现方式(完整版)

    Java栈的三种实现方式 什么是栈 栈(Stack)是一种常见的数据结构,它的特点是后进先出(LIFO,Last In First Out),就是存入栈的元素的顺序是先后顺序,最后存入的元素最先取出。栈只允许在栈顶进行插入和删除操作。 在程序中,栈常用于实现递归、函数调用和表达式求值等相关操作。 栈的实现方式 Java语言中,栈的实现通常有以下三种方式: 继…

    Java 2023年5月18日
    00
  • java springboot的概述、特点与构建介绍

    Java Spring Boot的概述、特点与构建介绍 1. 概述 Spring Boot是一个基于Spring框架的快速开发应用程序的工具。它提供了一种快速、便捷的方式来创建基于Spring的应用程序,同时也提供了一些默认的配置和约定,使得开发人员可以更加专注于业务逻辑的实现。 2. 特点 Spring Boot具有以下特点: 快速开发:Spring Bo…

    Java 2023年5月15日
    00
  • jsp实现局部刷新页面、异步加载页面的方法

    让我来为您详细讲解一下“JSP实现局部刷新页面、异步加载页面的方法”的完整攻略。 前言 JSP(Java Server Pages)是一种基于Java技术的Web开发技术,它允许开发人员在HTML标签中包含Java代码,并通过编译器将其转换为Java Servlet。JSP通常与MVC(Model-View-Controller)设计模式一起使用,它允许开发…

    Java 2023年6月15日
    00
  • 什么是重入锁?

    重入锁(Reentrant Lock)是一种可重入的互斥锁,它可以被同一个线程重复获取多次。在Java中,重入锁是通过java.util.concurrent.locks.ReentrantLock类来实现的。 下面是使用重入锁的完整使用攻略: 一、创建重入锁 使用重入锁需要先创建一个ReentrantLock对象。在创建ReentrantLock对象时,可…

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