冷饭新炒:理解JDK中UUID的底层实现 (2)

上面提到的UUID的具体布局只适用于date-time and MAC address(版本1)和date-time and MAC address, DCE security version(版本2),其他版本虽然采用了基本一样的字段分布,但是无法获取时间戳、时钟序列或者节点ID等信息

上面提到的UUID的具体布局只适用于date-time and MAC address(版本1)和date-time and MAC address, DCE security version(版本2),其他版本虽然采用了基本一样的字段分布,但是无法获取时间戳、时钟序列或者节点ID等信息

上面提到的UUID的具体布局只适用于date-time and MAC address(版本1)和date-time and MAC address, DCE security version(版本2),其他版本虽然采用了基本一样的字段分布,但是无法获取时间戳、时钟序列或者节点ID等信息

JDK中只提供了版本3和版本4的实现,但是java.util.UUID的布局采用了上面表格的字段

UUID的碰撞几率计算

UUID的总量虽然巨大,但是如果不停地使用,假设每纳秒生成超过1兆个UUID并且人类有幸能够繁衍到100亿年以后,总会有可能产生重复的UUID。那么,怎么计算UUID的碰撞几率呢?这是一个数学问题,可以使用比较著名的生日悖论解决:

冷饭新炒:理解JDK中UUID的底层实现

上图来源于某搜索引擎百科。刚好维基百科上给出了碰撞几率的计算过程,其实用的也是生日悖论的计算方法,这里贴一下:

冷饭新炒:理解JDK中UUID的底层实现

上面的碰撞几率计算是基于Leach–Salz变体和版本4进行,得到的结论是:

103万亿个UUID中找到重复项的概率是十亿分之一

要生成一个冲突率达到50%的UUID至少需要生成2.71 * 1_000_000^3个UUID

有生之年不需要担心UUID冲突,出现的可能性比大型陨石撞地球还低。

冷饭新炒:理解JDK中UUID的底层实现

UUID的使用场景

基本所有需要使用全局唯一标识符的场景都可以使用UUID,除非对长度有明确的限制,常用的场景包括:

日志框架映射诊断上下文中的TRACE_ID

APM工具或者说OpenTracing规范中的SPAN_ID

特殊场景下数据库主键或者虚拟外键

交易ID(订单ID)

等等......

JDK中UUID详细介绍和使用

这里先介绍使用方式。前面提到JDK中应用的变体是Leach-Salz(变体2),提供了namespace name-based MD5(版本3)和random(版本4)两个版本的UUID生成实现,实际上java.util.UUID提供了四种生成UUID实例的方式:

最常见的就是调用静态方法UUID#randomUUID(),这就是版本4的静态工厂方法

其次是调用静态方法UUID#nameUUIDFromBytes(byte[] name),这就是版本3的静态工厂方法

另外有调用静态方法UUID#fromString(String name),这是解析8-4-4-4-12格式字符串生成UUID实例的静态工厂方法

还有低层次的构造函数UUID(long mostSigBits, long leastSigBits),这个对于使用者来说并不常见

最常用的方法有实例方法toString(),把UUID转化为16进制字符串拼接而成的8-4-4-4-12形式表示,例如:

String uuid = UUID.randomUUID().toString();

其他Getter方法:

UUID uuid = UUID.randomUUID(); // 返回版本号 int version = uuid.version(); // 返回变体号 int variant = uuid.variant(); // 返回时间戳 - 这个方法会报错,只有Time-based UUID也就是版本1或者2的UUID实现才能返回时间戳 long timestamp = uuid.timestamp(); // 返回时钟序列 - 这个方法会报错,只有Time-based UUID也就是版本1或者2的UUID实现才能返回时钟序列 long clockSequence = uuid.clockSequence(); // 返回节点ID - 这个方法会报错,只有Time-based UUID也就是版本1或者2的UUID实现才能返回节点ID long nodeId = uuid.node();

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywysp.html