深入解析单例模式的七种实现

【 史上最全】测绘、遥感RS、地信GIS国家级比赛竞赛整理 目录Esri Esri 阅读详情

点击上方“芋道源码”,选择“置顶公众号”

技术文章第一时间送达!

源码精品专栏

 

来源:http://t.cn/E4J3ffX

  • 什么是单例模式

  • 如何实现单例模式呢?

  • 单例模式的七种实现

    • 第一种:懒汉式加载

    • 第二种:饿汉式加载

    • 第三种方式:synchronized 同步式

    • 第四种方式:双重检验锁:

    • 第五种方式:既要懒汉式加载,又要线程安全:静态内部类。

    • 第六种方式:反射和反序列化破坏单例

    • 第七种方式:最后一招,使用枚举

  • 总结


什么是单例模式

什么是单例模式呢? 我们引用一下维基百科:

单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。还有就是我们经常使用的servlet就是单例多线程的。使用单例能够节省很多内存。

如何实现单例模式呢?

我们引用一下维基百科:

实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。

好了,我们知道了单例模式的定义和如何使用单例的描述,接下来,就引用Linux Torvalds 的话:

Talk is cheap. Show me the code

让我们来看看单例模式的7种实现方式

单例模式的七种实现

第一种:懒汉式加载

懒汉式加载:最简单的单例模式:2步,1.把自己的构造方法设置为私有的,不让别人访问你的实例,2.提供一个static方法给别人获取你的实例.

img

懒汉式加载版本单例模式

我们可以看到,这是一个简单的获取单例的一个类,首先我们定义一个静态实例 single, 如何将构造方法变成私有的。并且给外界一个静态获取实例的方法。如果对象不是null,就直接返回实例,从而保证实例。也可以保证不浪费内存。这是我们的第一个实现单例模式的例子。很简单。但是有问题,我们后面再讲。

第二种:饿汉式加载

img

饿汉式加载版本单例模式

我们看到第二种单例模式,代码量比第一个少了很多,而为什么叫饿汉式呢?我们看代码,我们定义了一个静态的final的实例,并且直接new了一个对象,这样就会导致Single2 类在加载字节码到虚拟机的时候就会实例化这个实例,当你调用getInstance方法的时候,就会直接返回,不必做任何判断,这样做的好处是代码量明显减少了,坏处是,在你没有使用该单例的时候,该单例却被加载了,如果该单例很大的话,将会浪费很多的内存。

我们停下来思考一下

我们如何选择这两种实现方式呢?如果你的项目对性能没有要求,那么请直接使用饿汉式方法实现单例模式,既简单又方便。但是,大部分程序员都是有追求的,岂能不追求性能。那么我们看第一种方式,就是懒汉式,我们刚刚说过,懒汉式既保证了单例,又保证了性能。但是,他真的能保证单例吗?可以确定的是:在单线程模式下,毫无问题,但在复杂的多线程模式下,会怎么样呢?show me code .

测试用例:我们测试一下
img
测试用例

我们分析一下上面的代码,首先,我们验证的是什么呢?我们想验证多线程下获取懒汉式单例会不会出现错误。也就是出现一个以上的单例,我们如何做呢?首先我们定义一个Set对实例进行去重,然后创建1000个线程(Windows每个进程最多1000个线程,Linux每个进程最多2000个线程),每个线程都去获取实例,并添加到set中,实际上,我们应该使用Collections.synchronizedSet(set)获取一个线程安全的set,但是,这里为了方便,就直接使用HashSet了,然后main线程等待10秒,让1000个线程尽量都执行完毕。最后循环打印set的内容。在某些情况下,会出现2个实例,注意,是某些情况下,一定要多测试几次。下面是我们测试的结果:

img

测试结果

我们停下来思考一下:

我们通过测试用例发现:高并发情况下,我们的懒加载确实存在bug。为什么会这样呢?我们假设第一个线程进入getInstance方法,判断实例为null,准备进入if块内执行实例化,这时线程突然让出时间片,第二个线程也进入方法,判断实例也为null,并且进入if块执行实例化,第一个线程唤醒也进入if块进行实例化。这时就会出现2个实例。所以出现了bug。So, 我们想要性能(避免上面说的消耗不需要的内存),又要线程安全。那我们该怎么办呢?有点经验的同学心里肯定有数了。show me code.

第三种方式:synchronized 同步式

img

59{(V}0%MG546FRIF4(_9.png

这是我们的第三种方式,我们分析一下代码,我们可以看到,我们仅仅是在第一种懒汉式中加入了一个关键字,synchronized, 使用synchronized保证线程同步,保证同时只有一个进程进入此方法。从而保证并发安全。但是这样做完美吗?我们思考一下我们的代码:我们使用synchronized关键字,相当于每个想要进入该方法的获取实例的线程都要阻塞排队,我们仔细思考一下:需要吗?当实例已经初始化之后,我们还需要做同步控制吗?这对性能的影响是巨大的。是的,我们只需要在实例第一次初始化的时候同步就足够了。我们继续优化。

第四种方式:双重检验锁:

img

双重检验锁

我们继续分析一下代码:首先看getInstance方法,我们在方法声明上去除了synchronized关键字,多线程进入方法内部,判断是否为null,如果为null,多个线程同时进入if块内,此时,我们是用Single4 Class对象同步一段方法。保证只有一个线程进入该方法。并且判断是否为null,如果为null,就进行初始化。我们想象一下,如果第一个线程进入进入同步块,发现该实例为null,于是进入if块实例化,第二个线程进入同步内则发现实例已经不是null,直接就返回 了,从而保证了并发安全。那么这个和第三种方式又什么区别呢?第三种方式的缺陷是:每个线程每次进入该方法都需要被同步,成本巨大。而第四种方式呢?每个线程最多只有在第一次的时候才会进入同步块,也就是说,只要实例被初始化了,那么之后进入该方法的线程就不必进入同步块了。就解决并发下线程安全和性能的平衡。虽然第一次还是会被阻塞。但相比较于第三种,已经好多了。

我们还对一个东西感兴趣,就是修饰变量的volatile关键字,为什么要用volatile关键字呢?这是个有趣的问题。我们好好分析一下:
首先我们看,Java虚拟机初始化一个对象都干了些什么?总的来说,3件事情:

  1. 在堆空间分配内存

  2. 执行构造方法进行初始化

  3. 将对象指向内存中分配的内存空间,也就是地址

但是由于当我们编译的时候,编译器在生成汇编代码的时候会对流程进行优化(这里涉及到happen-before原则和Java内存模型和CPU流水线执行的知识,就不展开讲了),优化的结果式有可能式123顺序执行,也有可能式132执行,但是,如果是按照132的顺序执行,走到第三步(还没到第二步)的时候,这时突然另一个线程来访问,走到if(single4 == null)块,会发现single4已经不是null了,就直接返回了,但是此时对象还没有完成初始化,如果另一个线程对实例的某些需要初始化的参数进行操作,就有可能报错。使用volatile关键字,能够告诉编译器不要对代码进行重排序的优化。就不会出现这种问题了。

我们看到,小小的单例模式被我们弄得很复杂。但这就是一个程序员的追求,追求最好的性能,追求最好的代码。

那还有没有别的更好的办法呢?这个代码也太多了,代码可读性也不好。而且线程第一次进入还会阻塞,还能更完美吗?

第五种方式:既要懒汉式加载,又要线程安全:静态内部类。

img

我们来分析一下代码:相比较饿汉式(也就是第二种),我们增加了一个内部类,内部类中有一个外部类的实例,并且已经初始化了。我们回忆一下饿汉式有什么问题,饿汉式的问题是:在你没有使用该单例的时候,该单例却被加载了,如果该单例很大的话,将会浪费很多的内存.但是,我们现在引入了内部类的方式,虚拟机的机制是,如果你没有访问一个类,那么是不会载入该类进入虚拟机的。当我们使用外部类的时候其他属性的时候,是不会浪费内存载入内部类中的单例的。从而也就保证了并发安全和防止内存浪费。
但是,这样就能完美了吗?

第六种方式:反射和反序列化破坏单例

img

我们知道Java的反射几乎是什么事情都能做,管你什么私有的公有的。都能破坏。我们是没有还手之力的。精心编写的代码就被破坏了,而反序列化也很厉害,但是稍微还有点办法遏制。什么办法呢?重写readResolve方法。show me code。

img

我们看到:我们重写了readResolve方法,在该方法中直接返回了我们的内部类实例。重写readResolve() 方法,防止反序列化破坏单例机制,这是因为:反序列化的机制在反序列化的时候,会判断如果实现了serializable或者externalizable接口的类中包含readResolve方法的话,会直接调用readResolve方法来获取实例。这样我们就制止了反序列化破坏我们的单例模式。那反射呢?我们有办法吗?

第七种方式:最后一招,使用枚举

img

为什么使用枚举可以呢?枚举类型反编译之后可以看到实际上是一个继承自Enum的类。所以本质还是一个类。 因为枚举的特点,你只会有一个实例。我们看一下反编译的枚举类。

img

反编译的class字节码

我们看到,我们的hello包下的Single7枚举继承了java.lang.Enum<> 类。事实上就是一个类,但是我们这样就能防止反射破坏我们辛苦写的单例模式了。因为枚举的特点,而他也能保证单例。堪称完美!!!

总结

回到开始,我们引用了一些维基百科的话,我们再看看维基百科关于并发是怎么说的:

单例模式在多线程的应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率).

我们看到维基百科还是靠谱的。告诉了我们可以使用互斥锁来防止并发出现的问题。

而单例模式带来了什么好处呢?

  1. 对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销;

  2. 由于 new 操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻 GC 压力,缩短 GC 停顿时间。

小小的一个单例模式也是如此的复杂,耗费了我们很多的精力去写,去读一篇文章。可是,这就是我们的乐趣。任何一段小小的代码,我们都要精益求精。总有一天,我们会写出千万人用的优良代码。加油!!



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:

已在知识星球更新源码解析如下:


↓↓↓点下【好看】↓↓↓

↓↓↓艿艿【变丑】↓↓↓

HDR 人像肤色稳定实战:AE/AWB/ToneMap 冲突解耦与优先级裁决 人像 HDR 最容易“翻车”的就是**肤色飘**:AE 抢亮度、AWB 拉白点、TM 又在肩部压高光,三方各自“对”却合起来“错”。本文给出一套**工程可落地**的裁决策略:以**肤色 ROI 锚点**为最高约束,AE 先对脸部入射照度收敛,AWB 在**肤色先验 + 光源模型**下缓变,TM 采用**色相保持 + 中灰/肤色双锚**且时域一致化。配套**阈值与回归**(ΔE00、亮度漂移 RMS、频闪注入),把“主观对”的口径落到**可度量**,并给出逆光、多脸、霓虹等极端场景的**例外分流**。 阅读详情

相关推荐

持续集成介绍及Jenkins自动化测试部署

学习持续集成及jenkins的自动化测试部署

ouihsiad的博客 4579

单例模式的7种实现总结

目录单例模式介绍一、饿汉式二、懒汉式三、懒汉式+synchronized同步四、Double-Check式(注意有坑)五、Volatile + Double-Check式(最终版)六、Holder式七、枚举式八、防止JAVA通过反射修改构造器来攻击单例类参考资料 单例模式介绍   单例模式(Singleton Pattern)是 Java 中最简单、最常用的设计模式之一。单例模式提供了一种在多线...

麦田里的码农 876

第18届全国大学生智能汽车竞赛四轮车控制策略深度解析:从舵机PID到速度闭环

本文深度解析了第18届全国大学生智能汽车竞赛中四轮车的核心控制策略。从舵机PID方向控制的基础原理与机械校准入手,详细阐述了误差计算、PD控制等关键环节;进而深入探讨了基于编码器的速度闭环控制,包括增量式PI算法与速度决策逻辑。文章结合实战经验,提供了方向环与速度环的协同调参思路与避坑指南,旨在帮助参赛者构建稳定、高效的智能车控制系统。

potato的博客 465

单例模式的七种实现方式及优缺点

单例模式什么是单例模式为什么需要单例模式单例模式的基本构造常见的七种单例模式的写法饿汉式单例模式经典的单例模式(线程不安全)懒汉式单例模式(线程安全)双重检查实现懒汉式单例模式另一种懒汉式单例模式静态内部类实现单例模式枚举实现单例模式通过反射破坏单例模式单例模式的优点单例模式的缺点 什么是单例模式 简单来说,就是用来创建独一无二的,只有一个实例对象,是一种最简单的设计模式。 特点: 1.一个类只能...

weixin_43420278的博客 2481

Delft3D从入门到实践:安装、编译与首次模拟指南

本文为Delft3D初学者提供了一份详尽的从零开始指南。内容涵盖软件获取、许可证申请、图形界面安装、核心计算内核的编译环境搭建与编译步骤,以及最终整合运行首个水动力模拟的全流程。重点解决了Windows系统下Delft3D安装与编译的常见问题,帮助用户快速上手这一开源水动力与泥沙输运模拟工具。

weixin_29303701的博客 542

数据中心光模块升级实录:从200G QSFP56到400G QSFP-DD的踩坑指南

本文记录了数据中心从200G QSFP56升级至400G QSFP-DD光模块的完整实战经验。文章深入剖析了升级过程中面临的兼容性、链路预算、布线、散热与功耗管理等核心挑战,并提供了具体的解决方案与排坑指南,为高速网络升级提供了宝贵的实践参考。

butter的博客 482

单例模式深度解析:七种实现方式详解

本文系统介绍了单例模式的7种实现方式及其应用场景。主要内容包括:1)单例模式的核心思想是确保类只有一个实例并提供全局访问点;2)详细分析了懒汉式(基础版、同步方法版)、饿汉式、双重检查锁定、静态内部类、枚举和ThreadLocal等7种实现方式的优缺点;3)深入探讨了单例模式在反射攻击、序列化、性能优化等方面的防护措施;4)介绍了单例模式在分布式环境中的挑战及解决方案;5)总结了不同场景下的最佳实践选择建议。文章通过大量代码示例展示了各种实现的技术细节,为开发者提供了全面的单例模式应用指南。

油墨香^-^的博客 870

手把手教你学simulink实例:基于Simulink的风力发电系统建模与仿真

风力发电作为一种清洁、可再生的能源形式,近年来得到了快速发展。风力发电系统的性能优化和控制策略设计对于提高发电效率、降低运行成本具有重要意义。本项目旨在使用MATLAB/Simulink平台,对风力发电系统进行建模与仿真,研究其动态特性,并验证控制策略的有效性。通过建立风力发电机、传动系统、发电机及电力电子变换器等子系统的模型,实现对风力发电系统的全面分析。

MHD0815的博客 560

单例模式深度解析:从线程安全到分布式场景的七种实现与避坑指南

单例模式是面向对象设计中确保类只有一个实例并提供全局访问点的经典模式。其核心原理在于通过私有构造器、静态方法和特定初始化机制控制实例化过程,解决资源唯一性和状态一致性问题。在技术价值上,它有效管理数据库连接池、配置中心等共享资源,避免资源冲突,但需警惕线程安全、反射攻击等隐患。应用场景涵盖日志管理、全局计数器等需要强一致状态的组件。本文聚焦单例模式的七种演进实现,包括懒汉式、饿汉式、双重检查锁定及枚举式等,并深入探讨其在分布式环境下的局限性与替代方案。

weixin_28717969的博客 332

Python库CloudScraper详细使用(绕过 Cloudflare 的反机器人页面的 Python 模块)

CloudScraper是一个专门用于绕过Cloudflare反机器人保护的Python库,它基于requests库构建,能够处理Cloudflare的5秒盾、WAF和人机验证等防护机制。

数据知道的博客 1万+

玩转Docker小游戏项目系列: Docker部署中国象棋网页小游戏

玩转Docker小游戏项目系列: Docker部署中国象棋网页小游戏

jks212454的博客 444

七种方法实现单例模式

笔记来源:尚硅谷 目录一、单例模式的介绍二、饿汉式应用实例饿汉式(静态常量)饿汉式(静态代码块)三、懒汉式应用实例懒汉式(线程不安全,不推荐使用)懒汉式(线程安全,同步方法,也不推荐)四、双重检查(推荐使用)五、静态内部类(推荐使用)六、枚举(推荐使用) 一、单例模式的介绍 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。 比如Hibernate的SessionFactory,它充当数据存储源的代理,并负责创

weixin_43762820的博客 903

智能硬件产品 App 全球发布 第 1 章:全球 App 发布战略设计

本章阐述智能硬件 App 全球发布战略,涵盖市场分析、竞争格局、用户画像及资源配置。通过制定可执行的全球化推广路径,整合地区法规合规、渠道分发策略与营销活动设计,助力团队快速进入主流商店并确立品牌影响力。同时构建可量化的 KPI 监控体系,指导项目进度追踪与效果复盘,确保产品迭代持续优化,降低运营总成本。

moton2017的博客 157

单例模式(七种实现方法)

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 单例模式结构图: 单例模式有多种写法各有利弊,现在我们来看看各种模式写法。 1. 饿汉模式 public class Singleton { private static Singleton instance = new Singleton(); private Singleton (...

weixin_33759269的博客 149

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

设计模式——单例模式(七种实现方法)

1. 定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 单例模式结构图: 单例模式有多种写法各有利弊,现在我们来看看各种模式写法。 2. 饿汉模式 public class Singleton { private static Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return insta

程序员博客 508

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

单例模式的七种写法

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 单例模式结构图: 单例模式有多种写法各有利弊,现在我们来看看各种模式写法。 1. 饿汉模式 public class Singleton { private static Singleton instance = new Singleton(); ...

weixin_30305735的博客 65

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

设计模式——单例模式的七种实现方法

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 单例模式结构图: 单例模式有多种写法各有利弊,实际项目中用的也很多,面试中也有很多几乎是标配,现在我们来看看各种模式写法。 1. 饿汉模式 public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){ } public static Single

胡八一的博客 260

设计模式 | 单例模式及典型应用

单例是最常见的设计模式之一,实现的方式非常多,同时需要注意的问题也非常多。 本文主要内容: 介绍单例模式 介绍单例模式的N中写法 单例模式的安全性 序列化攻击 反射攻击 单例模式总结 介绍单例模式的典型应用 单例模式 单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象...

小旋锋 的博客 2368

设计模式-02 | 关于Java单例模式的七种实现方式

设计模式——单例模式 单例模式: 单例类只能有一个实例 单例类必须自己创建自己的唯一实例 单例类必须给其他所有对象提供这一实例 单例模式的七种实现形式: 1. 饿汉式 过程特点:先进行类的初始化,在程序执行的时候变量已经是初始化之后的了; 线程安全:饿汉式是线程安全的单例模式,因为从代码来看,进入程序后首先就初始化了static变量,之后调用getInstance()的时候,事实上s1是已经...

是袁同学呀 176

设计模式——单例模式(七种实现方法)

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 饿汉模式 public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){ } public static Singleton getInstance() ......

qq_36447261的博客 273

设计模式(5)——单例模式的七种实现方式

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 单例模式结构图: 单例模式有多种写法各有利弊,现在我们来看看各种模式写法。 1. 饿汉模式 public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){ ...

liinux-Talk is cheap,show me the code. 171

面向对象语言&大厂面试必问的单例设计模式——手撕七种单例模式

设计模式——手写八种单例模式前言+说明一、懒汉式加载1、非线程安全的懒汉式加载 前言+说明 ❤️旺仔兄弟们!这个是java语言编写的八种单例模式,总共两大类:饿汉式和懒汉式! 如果觉得博主分享的不错,希望能留下您的一键❤️三连❤️(点赞+评论+收藏) ,您的支持就是我前进的动力❤️,您的三连对我特别重要。 注明:下述内容只用于学习交流所用,禁止用于商业销售。同时也希望旺仔兄弟们能提出改善文章的宝贵意见,期待与大家共同进步❤️!     这种模式涉及到一个单一的类,该

FullChair的博客 1094

【面试干货】单例模式的七种写法

你知道实现单例模式有多少种? 你知道反序列会给单例模式带来什么影响? 答案就在本文,欢迎阅读

769

Android设计模式之单例模式的七种写法

一 单例模式介绍及它的使用场景 单例模式是应用最广的模式,也是我最先知道的一种设计模式,在深入了解单例模式之前,每当遇到如:getInstance()这样的创建实例的代码时,我都会把它当做一种单例模式的实现。其实经常使用的图片加载框架ImageLoader的实例创建就是使用了单例模式,因为这个ImageLoader中含有线程池、缓存系统、网络请求,很消耗资源,不应该创建多个对象,这时候就需要

hehongdan的博客 688

Java——单例模式的七种写法

单例模式的七种写法 第一种(懒汉,线程不安全): public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { ...

命中的缘分的博客 510

设计模式(二)单例模式的七种写法

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。 单例模式结构图: 单例模式有多种写法各有利弊,现在我们来看看各种模式写法。 1. 饿汉模式 public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){ ...

hyddhy的博客 167
上一篇: 分布式作业系统 Elastic-Job-Lite 源码分析 —— 运维平台
下一篇: 如何用九条命令在一分钟内检查 Linux 服务器性能?
公众号-芋道源码
博客等级 码龄10年 1636粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值