聊一聊java中的HashMap,ConcurrentHashMap以及Collections.SynchronizedMap

【数据类型】Collections.synchronizedMap 多线程Map,与HashMap的不同 Collections.synchronizedMap 是 Java 中提供的工具方法,用于创建一个同步(线程安全)的 Map。它接受一个现有的 Map 对象,并返回一个通过同步包装后的 Map。// 创建一个普通的 HashMap Map < String , Integer > hashMap = new HashMap < >(); 阅读详情

什么是红黑树?

鉴于一定会提到红黑树,那么就先来了解了解它吧。

红黑树(Red Black Tree)是一种自平衡的二叉查找树,是在计算机科学中常用的一种数据结构,典型的用途是实现关联数组。它是在1972年由Rudolf Bayer发明的,当时被称为平衡二叉B树(symmetric binary B-trees),后来在1978年被Leo J. Guibas和Robert Sedgewick修改为如今的红黑树。

红黑树具有如下性质:

  1. 每个节点都有一个颜色属性,可以是红色或黑色。
  2. 根节点是黑色的。
  3. 所有叶子节点(NIL节点或空节点)都是黑色的。
  4. 如果一个节点是红色的,则它的两个子节点都是黑色的。
  5. 从任一节点到其每个叶子节点的所有路径都包含相同数量的黑色节点,这被称为黑色节点的“路径长度相等”。
  6. 红黑树的最长路径不会超过最短路径的两倍,这确保了红黑树的高度始终在对数级别。

由于红黑树的这些性质,它在插入、删除和查找操作时的最坏情况运行时间非常良好,能在O(log n)时间内完成。因此,红黑树在实践中是高效的,特别适用于搜索、插入和删除操作较多的情况。

什么是链表?

同样,简单再回忆下链表。

链表(Linked List)是一种常见的数据结构,它由一系列节点(Node)组成,每个节点包含两部分:数据域和指针域。数据域用于存储元素值,而指针域则用于指向链表中的下一个节点。链表中的第一个节点被称为头节点(Head),最后一个节点通常指向空(Null),表示链表的结束。

链表的主要特点包括:

  1. 动态分配:链表的大小可以在运行时动态地增长或缩小,不需要预先分配固定大小的内存空间。

  2. 插入和删除效率高:在已知某一节点位置的情况下,链表的插入和删除操作通常只需要修改相邻节点的指针,因此效率相对较高。

  3. 顺序访问:链表中的元素是按照线性顺序链接在一起的,访问某个元素需要从头节点开始依次遍历。

  4. 内存利用率高:链表可以充分利用计算机内存中的碎片空间,不需要像数组那样要求连续的内存块。

链表有多种类型,其中最常见的是单向链表(Singly Linked List)和双向链表(Doubly Linked List)。

  • 单向链表:每个节点只有一个指针,指向下一个节点。单向链表只能从头节点开始,沿一个方向遍历整个链表。

  • 双向链表:每个节点有两个指针,一个指向前一个节点,另一个指向后一个节点。双向链表可以从任意节点开始,向前或向后遍历链表。

此外,还有循环链表(Circular Linked List),它的尾节点指针不是指向空,而是指回头节点,形成一个闭环。

链表在实际应用中有广泛的用途,例如用于实现栈、队列等数据结构,以及在需要频繁进行插入和删除操作的场景中作为数据的存储结构。然而,链表的随机访问效率较低,因为需要从头节点开始遍历才能找到特定位置的元素。因此,在选择使用链表时需要根据具体需求进行权衡。

链表与红黑树对比:

结构和特性:

  • 链表:链表由一系列节点组成,每个节点包含数据部分和指向下一个节点的指针。链表可以动态地改变其长度,并且可以在任何位置插入或删除节点。这种灵活性使得链表在处理插入或删除操作时更加高效。
  • 红黑树:红黑树是一种特殊的平衡二叉搜索树,它具有一系列特定的性质,如节点颜色(红色或黑色)、根节点必须是黑色、叶节点(NIL)是黑色的等。这些性质保证了红黑树在插入、删除和查找操作中都能保持相对平衡,从而确保这些操作的时间复杂度为O(log n)。

查找效率:

  • 链表的查找效率较低,因为需要从头节点开始遍历整个链表来找到目标节点,时间复杂度为O(n)。
  • 红黑树的查找效率较高,由于它的平衡性,可以确保查找路径相对较短,时间复杂度为O(log n)。

插入和删除操作:

  • 在链表中插入和删除节点相对容易,只需要更新节点的指针即可。然而,如果链表很长,那么找到要插入或删除的位置可能会很耗时。
  • 红黑树的插入和删除操作虽然相对复杂,但由于其平衡性,这些操作的时间复杂度仍然是O(log n)。

内存使用:

  • 链表在存储元素时需要额外的空间来存储节点之间的连接关系,这会增加一定的内存消耗。然而,链表可以充分利用内存碎片,提高内存的利用率。
  • 红黑树在存储元素时不需要额外的空间来存储节点之间的连接关系,但其节点结构相对复杂,每个节点包含更多的信息(如颜色、父节点指针等)。

适用场景:

  • 链表常用于需要频繁进行插入和删除操作的数据集合,特别是在不需要频繁查找的情况下。此外,链表也常用于实现自定义的内存管理器、事件处理、深度优先搜索等场景。
  • 红黑树则更适用于需要频繁进行查找、插入和删除操作的数据集合。由于其平衡性,红黑树在数据库系统、操作系统、图形处理系统等多个领域都有广泛的应用。

综上所述,链表和红黑树各有其优势和适用场景。在选择使用哪种数据结构时,需要根据具体的应用需求和场景来进行权衡和选择。

OK,接下来进入正题,一起来看看java中的HashMap,ConcurrentHashMap以及Collections.SynchronizedMap

HashMap

Java 7 中的 HashMap

实现原理:

  1. 数据结构:Java 7 中的 HashMap 使用数组和链表来存储键值对。当某个桶(bucket)的链表长度达到阈值(默认为 8)时,链表会转换为红黑树。但 Java 7 中实际上并没有实现红黑树的转换,这是 Java 8 中的一个改进。
  2. 哈希函数:通过键的 hashCode() 方法计算哈希值,然后通过哈希值确定键在数组中的位置。
  3. 扩容:当 HashMap 中的元素数量超过数组容量的一定比例(加载因子,默认为 0.75)时,会进行扩容,即创建一个新的数组,并将原数组中的元素重新计算哈希值后放入新数组。

Java 8 中的 HashMap

实现原理:

  1. 数据结构:Java 8 中的 HashMap 在 Java 7 的基础上进行了优化。当某个桶的链表长度达到阈值(默认为 8)时,链表会转换为红黑树,以提高查找效率。当树的大小小于 6 时,又会退化为链表。
  2. 哈希函数:与 Java 7 相同,通过键的 hashCode() 方法计算哈希值。
  3. 扩容:与 Java 7 相同,当元素数量超过数组容量的一定比例时,会进行扩容。

变化:

  • 引入了红黑树,优化了性能。
  • 链表转红黑树的阈值是 8,红黑树转链表的阈值是 6。

ConcurrentHashMap

Java 7 中的 ConcurrentHashMap

实现原理:

  1. 分段锁:ConcurrentHashMap 在 Java 7 中使用分段锁(Segment)来实现并发控制。每个 Segment 维护着自己的锁和哈希表,多个线程可以并发地操作不同的 Segment。
  2. 哈希函数和扩容:与 HashMap 类似,通过键的 hashCode() 方法计算哈希值,并确定键在数组中的位置。当某个 Segment 中的元素数量超过容量的一定比例时,会进行扩容。

Java 8 中的 ConcurrentHashMap

实现原理:

  1. CAS 和同步控制:Java 8 中的 ConcurrentHashMap 放弃了分段锁的设计,转而使用 CAS(Compare-and-Swap)操作和精细化的同步控制来实现更高的并发性能。
  2. Node 数组和链表/红黑树:与 HashMap 类似,ConcurrentHashMap 也使用数组和链表/红黑树来存储键值对。当某个桶的链表长度达到一定阈值时,会转换为红黑树。
  3. 扩容:当整个 ConcurrentHashMap 的元素数量超过数组容量的一定比例时,会进行扩容。在扩容过程中,会利用 CAS 操作和同步控制来确保线程安全。

变化:

  • 放弃了分段锁的设计,使用 CAS 和同步控制实现更高的并发性能。
  • 引入了红黑树,优化了性能。
  • 扩容机制也有所改变,更加高效和线程安全。

总结来说,Java 8 对 HashMap 和 ConcurrentHashMap 都进行了优化,引入了红黑树来提高性能,并在 ConcurrentHashMap 中放弃了分段锁的设计,使用 CAS 和同步控制实现更高的并发性能。这些改进使得 Java 8 中的集合框架在并发和性能方面更加出色。

Collections.SynchronizedMap

Collections.synchronizedMap 是 Java 集合框架中提供的一个工具方法,用于创建一个线程安全的 Map。它接受一个现有的 Map 对象作为参数,并返回一个通过同步包装后的 Map。这个同步的 Map 在对其进行操作期间,其他线程无法修改其内容,从而确保了线程安全性。

当多个线程同时访问一个普通的 Map 时,可能会导致数据不一致的问题。为了避免这种问题,可以使用 Collections.synchronizedMap 方法来创建一个同步的 Map。这样,每个对 Map 的操作(如添加、删除、修改等)都会是原子的,从而保证了数据的一致性。

使用 Collections.synchronizedMap 创建的同步 Map 主要有以下特点:

  1. 线程安全:通过同步机制确保了对 Map 的操作是线程安全的。
  2. 原子性:对 Map 的每个操作都是原子的,即在执行过程中不会被其他线程打断。
  3. 互斥性:在对 Map 进行操作时,其他线程无法修改其内容。

需要注意的是,虽然 Collections.synchronizedMap 提供了线程安全的 Map,但在使用它时仍需要谨慎处理并发问题。例如,当迭代遍历 Map 时,即使使用了同步的 Map,如果在迭代过程中有其他线程修改了 Map,那么迭代结果可能会不一致。为了避免这种情况,可以在迭代时使用同步块来确保整个迭代过程的线程安全性。

总的来说,Collections.synchronizedMap 是一个方便且实用的工具,用于在 Java 中创建线程安全的 Map。但在使用时,仍需要根据具体场景和需求来谨慎处理并发问题。

关于扩容的进一步说明:

HashMap的扩容过程主要发生在其内部的数组无法容纳更多键值对时。以下是HashMap扩容的详细步骤:

  1. 判断是否需要扩容:当HashMap中的元素数量(size)超过了数组长度(capacity)与负载因子(load factor)的乘积时,就会触发扩容。负载因子是一个衡量HashMap是否需要扩容的阈值,其默认值为0.75。因此,扩容的条件可以表示为:size > capacity * loadFactor。
  2. 创建新的数组:一旦确定需要扩容,HashMap会创建一个新的数组,其容量通常是原数组容量的两倍。这样做的好处是,新的数组可以容纳更多的元素,同时保持了相对较低的哈希冲突概率。
  3. 重新计算哈希值并迁移元素:扩容后,HashMap中的每个键值对都需要重新计算哈希值,并根据新的哈希值确定在新数组中的位置。这个过程涉及到大量的元素迁移。对于每个键值对,HashMap会计算其键的哈希值,并使用这个哈希值来确定在新数组中的索引位置。然后,将键值对放入新数组对应索引位置的桶中。

在Java 8及以后的版本中,HashMap引入了红黑树来优化性能。当某个桶中的链表长度超过一定阈值(默认为8)时,链表会转换为红黑树,以提高查找效率。在扩容过程中,如果原桶中的结构是红黑树,那么扩容后对应的桶也会保持红黑树的结构。

需要注意的是,HashMap的扩容操作是一个相对耗时的过程,因为它涉及到大量元素的迁移和重新哈希。因此,在初始化HashMap时,如果能预估到未来可能存储的数据量,合理设置初始容量(initial capacity)和负载因子,可以有效减少扩容的频率和性能损失。

另外,HashMap的扩容并不是线程安全的。如果在多线程环境下使用HashMap,并且多个线程同时修改HashMap,可能会导致数据不一致。如果需要线程安全的HashMap,可以考虑使用ConcurrentHashMap。

Hashtable, Collections.SynchronizedMap和ConcurrentHashMap线程安全实现原理的区别以及性能测试 Hashtable,Collections.SynchronizedMap和ConcurrentHashMap线程安全实现原理的区别以及性能测试 这三种 Map 都是 Java 中比较重要的集合类,虽然前两个不太常用,但是因为与多线程相关,所以关于这几种 Map 的对比已经成为了 Java 面试时的高频考点。首先要说明的是,其中每一个单独拎出来都足够支撑一篇长篇大论的技术文章,所以本文把重点放在了... 阅读详情

相关推荐

Java 集合操作之 Collections.synchronizedMap()

Java 集合操作之 Collections.synchronizedMap()

HY 685

JAVA数据结构篇--10理解Collections.synchronizedMap

理解Collections.synchronizedMap

拽着尾巴的鱼儿的博客 2067

synchronizedMap 和 concurrenthashmap 分别适用于什么场景?

如何线程安全的使用HashMap 了解了 HashMap 为什么线程不安全,那现在看看如何线程安全的使用 HashMap。这个无非就是以下三种方式: Hashtable ConcurrentHashMap Synchronized Map 常用的有Collections工具类的synchronizedMap创建的Map对象,是属于线程安全的;其次就是并发包下的ConcurrentHashMap类。...

数字成都 3202

Collections.synchronizedMap

Collections.synchronizedMap()方法来获取一个线程安全的集合(Collections.synchronizedMap()实现原理是Collections定义了一个SynchronizedMap的内部类,这个类实现了Map接口,在调用方法时使用synchronized来保证线程同步,当然了实际上操作的还是我们传入的HashMap实例,简单的说就是Collections.sy...

qq_37538698的博客 3030

紫光同创PDS软件操作指南:如何为FPGA新增自定义Flash型号

本文详细介绍了在紫光同创PDS软件中为FPGA新增自定义Flash型号的完整操作指南。针对官方支持列表之外的SPI Flash芯片,文章从理解FPGA配置逻辑入手,逐步讲解如何通过扫描Flash ID、在Flash Operator中精准填写参数、转换.sbit文件,最终完成固化的全过程,并分享了高级技巧与常见问题排查方法,帮助工程师摆脱对预设型号的依赖,实现灵活选型。

weixin_29204749的博客 326

3D视觉-激光三角测量法的概述和原理

激光三角法位移测量的原理是,用一束激光以某一角度聚焦在被测物体表面,然后从另一角度对物体表面上的激光光斑进行成像,物体表面激光照射点的位置高度不同,所接受散射或反射光线的角度也不同,用。激光三角测量法是一种通过图像采集系统采集被测物表面漫反射的激光轮廓,进而基于设备已知的相对位置通过算法处理,获得被测物表面的三维轮廓数据,进而还原目标物体三维空间信息的方法。采用激光三角原理和回波分析原理进行非接触位置、位移测量的精密传感器, 广泛应用于位置、位移 、厚度、半径、形状、振动、距离等几何量的工业测量。

qq_20660115的博客 3921

synchronizedMap与ConcurrentHashMap

HashMap非线程安全,即任一时刻可以有多个线程同时写 HashMap,可能会导致数据的不一致。 如果需要满足线程安全,可以用 Collections 的 synchronizedMap 方法使HashMap 具有线程安全的能力,或者使用 ConcurrentHashMap。 **synchronizedMap与ConcurrentHashMap:**两者由于实现原理稍有不同,因此在读与写的性能上也会有所差异。接下来通过编写测试程序对两者的读写性能分别做比较。 测试类: import java.util.

qq1328585964的博客 1158

FPGA实战:SRIO接口数据流控制与回环测试详解

本文详细解析了FPGA中SRIO接口的数据流控制机制与回环测试实战。通过剖析SRIO IP核的AXI4-Stream接口握手时序(tvalid/tready/tlast),重点阐述了HELLO数据包格式与状态机设计,并提供了完整的Verilog代码示例。文章以回环测试为核心验证手段,指导开发者排查常见问题,为FPGA高速互连通信设计提供实用指南。

weixin_29173777的博客 425

HashMap与 ConcurrentHashMap与。SynchronizedMap –如何在Java中同步HashMap

HashMap是Java中非常强大的数据结构。我们每天都在几乎所有应用程序中使用它。我之前写过很多关于如何实现Threadsafe缓存,如何将Hashmap转换为Arraylist的示例。 我们在以上两个示例中都使用了Hashmap,但是这些是Hashmap的非常简单的用例。HashMap is a non-synchronized集合类。 您有以下任何问题吗? ConcurrentHashMap和Collections.synchronizedMap(Map)有什么区别? 在性能方面,Concu

allway2的博客 633

FreeRTOS笔记(十五)FreeRTOS总结

文章目录01 - 裸机和FreeRTOS区别1.1 - 裸机1.2 - FreeRTOS1.3 - 区别02 - 对FreeRTOS的感受03 - 推荐 上一文链接:FreeRTOS笔记(十四)[简] 软件定时器、事件组、任务通知 01 - 裸机和FreeRTOS区别   学完FreeRTOS,应该要自己总结一下FreeRTOS和裸机的区别,宏观上说,FreeRTOS是一个运行在裸机上的微内核,...

单眼皮根号三的博客 4114

USB3.0 Type-B连接器SSTX/SSRX信号定义常见错误与硬件设计避坑指南

本文详细解析了USB3.0 Type-B连接器中SSTX/SSRX信号的定义标准与常见设计错误。针对连接器厂商图纸可能出现的信号标识错误,提供了实用的排查方法和硬件设计避坑指南,帮助工程师避免因引脚定义颠倒导致的通信降级或故障,确保USB3.0高速传输的稳定性。

gg901的博客 1267

Hashtable,ConcurrentHashMap与Collections.synchronizedMap关键源码

一,Collections.synchronizedMap 1,构造 public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) { return new SynchronizedMap<>(m); } 2.为什么线程安全

bai_ye_的博客 1507

Windows与Linux安装miniconda并启动python项目及指令

官方介绍:Miniconda 是 conda 的免费最小安装程序。它是 Anaconda 的一个小型引导版本,仅​​包含 conda、Python、它们都依赖的包以及少量其他有用的包(例如 pip、zlib 等)。如果您需要更多软件包,请使用该 命令从 Anaconda 公共存储库或其他渠道(例如 conda-forge 或 bioconda)默认提供的数千个软件包中进行安装。minicoda下载地址最好挂个梯子。如果你需要指定版本的conda,可以在这里下载历史版本的miniconda。

一直走的很慢的鸭子 3191

Java笔记_Collections.synchronizedMap、Hashtable与ConcurrentHashMap

以下内容为从网上摘抄整理而来,仅用于本人知识积累 Collections.synchronizedMap Collections.synchronizedMap是怎么实现线程安全的? 在SynchronizedMap内部维护了一个普通对象Map,还有排斥锁mutex,如图 Collections.synchronizedMap(new HashMap<>(16)); 我们在调用这个方法的时候就需要传入一个Map,可以看到有两个构造器,如果你传入了mutex参数,则将对象排斥锁赋值为传入的.

weixin_42547014的博客 904

Altium Designer(AD)PCB拼版——两种方法教程

本文详细介绍了PCB拼版的设计要点与操作方法。主要内容包括:拼版目的(解决小尺寸夹持问题、提高利用率、降低成本)和三大连接方式(V-CUT、邮票孔、空心连接条)的特点与参数设置;工艺边设计规范(宽度、定位孔、Mark点等要求);拼版尺寸限制与常见错误检查;以及两种具体拼版操作方法(特殊粘贴和拼版阵列),并附有工艺边、定位孔、Mark点的绘制步骤示意图。同时提供了硬件工程师笔试面试相关资源链接。全文系统阐述了PCB拼版的核心技术和操作流程,为电子设计人员提供了实用指导。

XU157303764的博客 7601

【光伏风电功率预测】基于 ICEEMDAN + MSCNN-BiGRU-Attention 的并行预测模型

本文提出一种基于ICEEMDAN分解与多尺度深度学习的光伏/风电功率并行预测框架。针对多能源、多时间尺度、强非平稳特性带来的建模挑战,该模型首先通过改进的ICEEMDAN算法将原始功率序列分解为不同频段的IMF分量;随后为每个IMF构建包含多尺度CNN、双向GRU和注意力机制的子模型,实现局部特征提取与时序依赖建模;最后通过并行预测与重构获得最终功率输出。实验表明,该方法能有效解决模式混叠问题,提升预测精度,并支持光伏/风电的独立或联合预测部署,适用于风光联合调度等工程场景。

专注AI大模型,软件混淆,授权 155

Collections.synchronizedMap()与ConcurrentHashMap的区别

前面文章提到Collections.synchronizedMap()与ConcurrentHashM两者都提供了线程同步的功能。那两者的区别在哪呢?我们们先来看到代码例子。 下面代码实现一个线程对map进行写操作,另一个线程,读出并打印map数据。 package test.map; import java.util.Collections; import java.util.HashM...

AlbenXie的博客 917

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Collections.synchronizedMap()、ConcurrentHashMap、Hashtable之间的区别

为什么要比较Hashtable、SynchronizedMap()、ConcurrentHashMap之间的关系?因为常用的HashMap是非线程安全的,不能满足在多线程高并发场景下的需求。 那么为什么说HashMap是线程不安全的?具体参阅关于java集合类HashMap的理解 如何线程安全的使用HashMap 了解了 HashMap 为什么线程不安全,那现在看看如何线程安全的使用 Has...

NiFeiGe的博客 681

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

HashMap、ConcurrentHashMap和SynchronizedMap – 哈希表在Java中的多线程同步处理

原文链接:http://crunchify.com/hashmap-vs-concurrenthashmap-vs-synchronizedmap-how-a-hashmap-can-be-synchronized-in-java/ 在Java中,HashMap是一个非常有用的数据结构。几乎每一个Java应用都会使用到它。我之前的博文中有介绍过如何实现一个线程安全的缓存,在这个例子中,我就使用到...

tklwj的专栏 788

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Difference between ConcurrentHashMap and Collections.synchronizedMap and Hashtable in Java

Addthis Javarevisited Blog about my experience in Java programming, SQL, UNIX, Interview questions, FIX Protocol, Tibco RV, JavaScript, jQuery, Equity trading technologies, SQL, XM

Schen6 Online Life 1178

11. SynchronizedMap vs ConcurrentHashMap

是两种常用的线程安全 Map 实现,但它们在设计目标、并发性能和使用场景上有显著差异。在 Java 多线程编程中,

sinat_33739100的博客 797

HashMap、ConcurrentHashMap和SynchronizedMap – 哈希表在Java中的同步处理

原文链接:http://crunchify.com/hashmap-vs-concurrenthashmap-vs-synchronizedmap-how-a-hashmap-can-be-synchronized-in-java/ 在Java中,HashMap是一个非常有用的数据结构。几乎每一个Java应用都会使用到它。我之前的博文中有介绍过如何实现一个线程安全的缓存,在这个例子中,我就使用到了H

逆水行舟 1万+

java hashmap同步问题_SynchronizedMap和ConcurrentHashMap同步方式比较

在开始之前,先介绍下Map是什么?javadoc中对Map的解释如下:An object thatmaps keys to values. A mapcannot contain duplicate keys; each key can map to at most one value.This interface takes the place of the Dictionary clas...

weixin_29146313的博客 408

如何线程安全的使用HashMap

如何在高并发下安全使用HashMap?本文深入浅出带领大家了解三种最常见的方法!让我们一起掌握这个面试常问知识点!!

CodeSuc 的技术博客 1690
上一篇: 聊聊java中的CountDownLatch,CyclicBarrier,Semaphore
下一篇: java中使用雪花算法(Snowflake)为分布式系统生成全局唯一ID
Jack_abu
博客等级 码龄10年 633粉丝 78原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack_abu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值