首页 > 其他分享 >创建型模式-单例模式

创建型模式-单例模式

时间:2024-09-15 10:50:12浏览次数:3  
标签:创建 模式 instance 实例 线程 private 单例 static

单例模式有两种常见的实现方式:饿汉式懒汉式。以下是它们的代码示例:

1. 饿汉式(Eager Initialization)

在类加载时就创建实例,线程安全,适用于单例对象耗费资源较小的场景。

public class SingletonEager {
    // 在类加载时就创建实例
    private static final SingletonEager instance = new SingletonEager();

    // 私有构造方法,防止外部实例化
    private SingletonEager() {}

    // 提供全局访问点
    public static SingletonEager getInstance() {
        return instance;
    }
}

优点

  • 简单直观
  • 线程安全,不需要同步

缺点

  • 即使不使用该实例,类加载时也会创建对象,可能造成资源浪费。

2. 懒汉式(Lazy Initialization)

在第一次调用 getInstance() 时才创建实例,适用于单例对象较耗资源且不一定每次都使用的场景。

2.1 线程不安全的懒汉式:
public class SingletonLazy {
    // 延迟初始化
    private static SingletonLazy instance;

    // 私有构造方法
    private SingletonLazy() {}

    // 提供全局访问点(线程不安全)
    public static SingletonLazy getInstance() {
        if (instance == null) {
            instance = new SingletonLazy();
        }
        return instance;
    }
}

优点

  • 按需加载,节省资源

缺点

  • 线程不安全,多个线程可能同时创建多个实例
2.2 线程安全的懒汉式(同步方法):
public class SingletonLazyThreadSafe {
    private static SingletonLazyThreadSafe instance;

    private SingletonLazyThreadSafe() {}

    // 通过同步锁保证线程安全
    public static synchronized SingletonLazyThreadSafe getInstance() {
        if (instance == null) {
            instance = new SingletonLazyThreadSafe();
        }
        return instance;
    }
}

优点

  • 线程安全,简单易懂

缺点

  • 每次获取实例都需要同步,性能开销较大
2.3 双重检查锁(Double-Check Locking):
public class SingletonLazyDoubleCheck {
    private static volatile SingletonLazyDoubleCheck instance;

    private SingletonLazyDoubleCheck() {}

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

优点

  • 线程安全,且只在第一次创建时进行同步,性能较好

缺点

  • 代码较复杂,需要注意 volatile 的使用

3. 静态内部类(推荐使用)

静态内部类的方式结合了懒汉式和饿汉式的优点,线程安全且高效。

public class SingletonStaticInnerClass {
    private SingletonStaticInnerClass() {}

    // 静态内部类
    private static class SingletonHolder {
        private static final SingletonStaticInnerClass INSTANCE = new SingletonStaticInnerClass();
    }

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

优点

  • 利用了类加载机制,保证线程安全
  • 延迟初始化,按需加载
  • 不需要同步,性能较高

这几种方式都可以实现单例模式,具体使用时可以根据项目的实际需求进行选择。

在 JDK 中,单例模式被广泛应用于很多核心类和工具类中。以下是一些经典的 JDK 类或组件使用单例模式的例子:

jdk中使用到的单例模式

1. java.lang.Runtime

Runtime 类用于与 JVM 交互,并提供了管理和控制 JVM 的方法。它使用了饿汉式单例。

Runtime runtime = Runtime.getRuntime();
  • 使用场景Runtime 提供了 JVM 相关的全局服务,比如执行操作系统命令、获取可用的内存和处理器数量等。
  • 实现:通过 getRuntime() 方法获取唯一实例,类加载时就创建实例。
2. java.awt.Desktop

Desktop 类提供了一些平台相关的桌面操作功能,如打开浏览器、邮件客户端等。它也是通过单例模式实现的。

Desktop desktop = Desktop.getDesktop();
  • 使用场景:用于与本地操作系统的桌面功能交互,如打开文件、发送邮件等。
  • 实现:通过 getDesktop() 方法获取唯一实例。
3. java.lang.System

System 类提供了许多静态方法,用于与系统环境交互,如读取环境变量、标准输入输出等。它虽然没有传统意义的 getInstance(),但其设计本质上是一种单例模式,主要通过静态方法提供系统服务。

System.out.println("Hello, World!");
  • 使用场景:处理标准输入输出流、系统属性、环境变量等。
  • 实现:通过静态方法提供全局访问,不允许实例化。
4. java.util.logging.LogManager

LogManager 类负责管理全局日志配置,确保整个应用程序中日志记录的一致性。

LogManager logManager = LogManager.getLogManager();
  • 使用场景:控制全局的日志配置,管理所有的 Logger 实例。
  • 实现:使用单例模式确保只有一个日志管理器实例在运行时存在。
5. java.sql.DriverManager

DriverManager 用于管理数据库驱动程序,并处理与数据库的连接请求。

Connection connection = DriverManager.getConnection(url, user, password);
  • 使用场景:管理数据库连接,加载和注册 JDBC 驱动程序。
  • 实现:通过静态方法管理数据库连接,全局管理驱动程序的加载。
6. java.util.Calendar

Calendar 类用来操作日期和时间的实例,在一些实现(如 GregorianCalendar)中也使用了单例模式。

Calendar calendar = Calendar.getInstance();
  • 使用场景:用于日期和时间的计算与操作。
  • 实现:通过 getInstance() 提供全局访问点。
7. java.nio.file.FileSystems

FileSystems 类用来管理文件系统的访问。

FileSystem fileSystem = FileSystems.getDefault();
  • 使用场景:获取文件系统的根路径,处理路径的文件操作。
  • 实现:通过 getDefault() 方法获取默认的文件系统,内部实现单例模式。

总结

这些 JDK 中的类,采用单例模式的原因通常是:

  • 确保系统中某个类只有一个实例,避免资源浪费。
  • 提供全局访问点,使得这些实例能够被多个地方访问和共享。
  • 方便管理与外部系统交互的资源,如日志管理器、数据库连接、文件系统、JVM 资源等。

标签:创建,模式,instance,实例,线程,private,单例,static
From: https://blog.csdn.net/wrxfxdd/article/details/142266617

相关文章

  • java 反射创建内部类
    Java反射创建内部类在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时检查或修改类的行为。内部类(InnerClass)则是一种特殊的类,它定义在另一个类的内部,并可以访问外部类的成员。本文将深入探讨如何使用Java反射来创建内部类的实例,并展示其在实际开发中的应用。内部类的基......
  • 设计模式-解释器模式-Interpreter Pattern
    系列文章目录总目录链接文章目录系列文章目录总目录链接设计模式-解释器模式-InterpreterPatternOverview1.解释器模式(InterpreterPattern)1.1.组成要素1.2.适用场景1.3.优点1.4.缺点1.5.示例代码(C++)2.解释器模式优缺点2.1.优点2.2.缺点3.解释器模式在实际开发中......
  • MVC项目实战-基于JSP的MVC设计模式实现投票系统
    前言本博客将介绍基于JSP的MVC设计模式实现投票系统,实现两个功能:功能一:投票功能二:查看投票结果 第一步:设计数据库,创建JavaWeb项目,配置pom.xml文件,创建实体类数据库: 数据库中的t_vote包含三个字段:id,v_name,v_numid:主键,一行数据的唯一标识v_name:参与投票的对象名......
  • 观察者模式:如何发送消息变化的通知?
    观察者模式是一种非常流行的设计模式,也常被叫作订阅-发布模式。观察者模式在现代的软件开发中应用非常广泛,比如,商品系统、物流系统、监控系统、运营数据分析系统等。现在我们常说的基于事件驱动的架构,其实也是观察者模式的一种最佳实践。当我们观察某一个对象时,对象传递出的每一个......
  • 读书笔记:Head First 设计模式
    HeadFirst设计模式EricFreemanPDF下载(亲测有效):https://baijiahao.baidu.com/s?id=1756899911272841212&wfr=spider&for=pc前言如何使用本书一些HeadFirst学习原则:可视化。图片更容易让人记住,文字放图片里使用会话式和个人化风格。会话式讲述内容。让学习者想得更深引......
  • 浅谈线程的创建方式
    引言在网上查询这个问题,大多回答是线程的创建方式有四种。继承Thread类实现Runnable接口实现Callable接口使用线程池但是这种说法是错误的,或者说是不正确的不严谨的。我的想法实际上,在Java中创建线程的方式只有一种,就是使用newThread()只有这样才能创建一个线......
  • 利用Python与Bokeh创建动态交互数据可视化
    Bokeh是一个用于创建交互式和动态数据可视化的强大工具,它可以帮助你在Python中展示数据的变化趋势、模式和关联性。本文将介绍如何使用Bokeh库在Python中创建动态数据可视化,并提供代码示例以供参考。Bokeh简介Bokeh是一个开源的Python可视化库,它允许用户创建交互式的图......
  • 【来学Vue吧】创建一个Vue项目
    ......
  • 企业数智化升级新模式【数据飞轮】,高效挖掘数据资产价值
    一、前言:企业数智化升级新模式【数据飞轮】,它是一种企业数智化升级新模式,旨在通过数据和业务的双向良性驱动,有效提升工作质效。数据飞轮在多个行业中被用来充分发挥数据中台的价值,为业务发展提供参考。数据飞轮的工作原理可以类比为飞轮效应:一开始,为了使飞轮转动起来,需要花费较大的......
  • 企业数智化升级新模式【数据飞轮】,高效挖掘数据资产价值
    一、前言:企业数智化升级新模式【数据飞轮】,它是一种企业数智化升级新模式,旨在通过数据和业务的双向良性驱动,有效提升工作质效。数据飞轮在多个行业中被用来充分发挥数据中台的价值,为业务发展提供参考。数据飞轮的工作原理可以类比为飞轮效应:一开始,为了使飞轮转动起来,需要花费较大的......