深入理解Java设计模式之单例模式

深入理解Java设计模式之单例模式

单例模式是最简单也是最常用的设计模式之一。在实际开发中,经常会遇到需要一个类只能创建一个实例的情况。单例模式保证一个类只有一个实例,并且提供一个全局访问点。本文将深入探讨Java设计模式中的单例模式。

什么是单例模式?

单例模式是指一个类只有一个实例,且该类能自行创建这个实例的一种模式。例如,一个应用中需要打印日志文件,为了避免多个线程写同一个文件导致文件混乱,可以使用单例模式来保证同一时间只能有一个线程在写文件。

单例模式的特点

单例模式有以下特点:

  • 单例类只有一个实例对象;
  • 该单例对象必须由单例类自行创建,且创建过程只能执行一次;
  • 单例类必须提供一个全局的访问点,让外部代码可以访问该单例对象。

单例模式的实现方式

单例模式有以下两种实现方式:

饿汉式

饿汉式是指在单例类被加载时,就创建唯一的实例对象。这种实现方式比较简单,但是可能导致资源浪费,因为可能创建的实例对象并没有被使用到。示例如下:

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

懒汉式

懒汉式是指在单例对象被使用时才去实例化它,也称为延迟加载。这种实现方式在多线程环境下可能会出现线程安全问题,因为多个线程可能同时判断该对象为null,并同时创建多个实例对象。为了解决这个问题,可以使用双重检查锁定来保证线程安全。示例如下:

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

在上面的代码中,使用了volatile关键字来保证instance变量的可见性和禁止指令重排。

单例模式的应用

单例模式在实际开发中有很多应用场景,例如:

  • 日志模块:保证多个线程写日志时只有一个线程在写;
  • 数据库连接池:保证多个线程共享同一个数据库连接池;
  • 缓存:保证多个线程共享同一个缓存对象。

单例模式的优缺点

单例模式的优点:

  • 单例模式可以保证一个类只有一个实例对象,节省系统资源;
  • 单例模式提供了一个全局访问点,方便其他代码获取该实例对象。

单例模式的缺点:

  • 单例模式容易造成内存泄漏;
  • 单例模式对OOP特性支持不友好,例如继承、多态等。

示例说明

以下是一个经典的双重检查锁定实现的单例模式示例:

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

另外,Java中的Runtime类使用了单例模式,保证只有一个Runtime实例对象。例如,以下代码获取Runtime实例对象:

Runtime runtime = Runtime.getRuntime();

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解Java设计模式之单例模式 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 如何在spring官网查找XML基础配置文件

    在spring官网查找XML基础配置文件的步骤 打开spring官网官网(https://spring.io/) 点击菜单栏上的”Get Started”选项 选择”XML Configuration”菜单栏选项 在弹出的页面上,可以查看到所有和XML配置相关的文档和示例 示例说明 生成XML配置文件示例: <?xml version=”1.0″ en…

    other 2023年6月25日
    00
  • Java中的static–静态变量你了解吗

    Java中的static–静态变量 1. 什么是静态变量 静态变量是在Java类中被标记为static的变量。与实例变量不同,静态变量属于类本身,而不是类的实例。因此,无论创建多少个类的实例,静态变量只有一份。 2. 静态变量的特点 静态变量在类加载时初始化,并且在整个程序运行期间保持不变。 所有该类的实例共享同一个静态变量。 静态变量可以通过类名直接访问…

    other 2023年6月28日
    00
  • hdmi之hpd

    HDMI之HPD HDMI,全称高清多媒体接口,是一种数字化的音视频传输接口标准。通常,当我们将一台台式或笔记本电脑连接至一个外接显示器、智能电视或音响中,都可以使用HDMI接口。 HDMI接口中有一个重要的信号标志,叫做HPD(Hot Plug Detect)。HPD是指当HDMI输入端口(也就是外接设备)上插入电缆时,,HDMI输出端口(也就是显示器、电…

    其他 2023年3月29日
    00
  • vue子路由跳转实现tab选项卡

    当使用Vue.js实现子路由跳转来实现tab选项卡时,可以按照以下攻略进行操作: 1. 设置路由 首先,您需要设置Vue的路由,以便支持子路由的跳转。以下是一个示例: // 定义路由 const routes = [ { path: ‘/’, component: Home, children: [ { path: ‘tab1’, component: Ta…

    other 2023年10月12日
    00
  • C语言基于考研的栈和队列

    C语言基于考研的栈和队列攻略 一、前言 在考研中,栈和队列是比较常见的数据结构,而在C语言中,栈和队列的实现十分简单和方便。本篇攻略旨在帮助初学者了解C语言中栈和队列的概念,并通过两个简单的示例代码帮助读者掌握如何实现基于考研的栈和队列。 二、栈的实现 栈是一种具有后进先出(Last-In-First-Out,简称LIFO)特性的数据结构,进栈和出栈操作都在…

    other 2023年6月27日
    00
  • C#Light Unity逻辑热更新解决方案0.20 发布

    C#Light Unity逻辑热更新解决方案0.20 发布 我们非常高兴地宣布C#Light Unity逻辑热更新解决方案0.20的发布。这个版本是我们最新的更新,旨在帮助Unity开发者更轻松地实现热更新功能,并提供更好的运行时性能。 C#Light概述 C#Light是专门为Unity开发者设计的热更新方案,它可以在运行时动态加载C#代码,并且可以与Un…

    其他 2023年3月28日
    00
  • 安装mysq 5.7.20 解压版遇到的坑(推荐)

    下面是关于安装MySQL 5.7.20 解压版所遇到的坑以及解决方案的完整攻略: 1. 下载与解压 首先,我们需要先从MySQL官网下载MySQL 5.7.20的压缩包版本,具体网址为:https://dev.mysql.com/downloads/mysql/5.7.html。选择“MySQL Community Server”后,可以根据操作系统进行选择…

    other 2023年6月27日
    00
  • 【基础】css实现多重边框的5种方式

    【基础】CSS实现多重边框的5种方式 CSS是网页设计中必不可少的一部分,它可以用来实现各种炫酷的效果。本文将介绍CSS实现多重边框的5种方式,希望对你的网页设计有所帮助。 1. 使用box-shadow box-shadow属性是CSS3中新增的一个属性,可以用来在HTML元素周围创建一个阴影。我们可以设置多个 box-shadow 属性来实现多重边框。 …

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部