java唯一字符串ID生成方案详解
工作中经常会有生成唯一字符串的需求。通常最容易想到的是UUID。UUID的唯一性毋庸置疑,但是32位的长度也容易让人退避三舍。也曾经想过参考《短网址生成方案》来生成一串ID,但是试验了一下发现唯一性不太好。

最终采用的方案是时钟方案,简单来说就是用当前时间戳做唯一ID。
采用时间戳做ID,秒或毫秒都容易产生重复,换成纳秒在单节点上就没问题了。参考百度百科关于纳秒的描述就能清楚为什么纳秒级别的时间戳不会产生重复:
光在真空中一纳秒仅传播0.3米。个人电脑的微处理器执行一道指令(如将两数相加)约需2至4纳秒。
我们生成一条唯一ID所需的CPU指令绝不止一道,因此用纳秒作单机唯一ID是绰绰有余的。在测试中发现,即使是千分之一纳秒也足够我们在PC机上生成唯一ID了。
至于长度:对原始值做一次Base62处理,长度就能缩减到令人满意的程度。
不多废话,直接上代码:
public static synchronized String gen() {
StringBuilder builder = new StringBuilder(System.nanoTime() / 1000 + "");
if (SEQ.incrementAndGet() % 10 == 0) {
SEQ.incrementAndGet();
}
builder.append(FORMAT.format(SEQ.get()));
if ((MAX_PAD_SIZE - 1) == SEQ.get()) {
SEQ.set(1);
}
long v = Long.parseLong(builder.reverse().toString());
return Base62.encode(v);
}
这里用千分之一纳秒做基数(经测试,基数在10w分之一纳秒内都是安全的),再加上1~99的顺序号来生成唯一ID。最终可以保证在大于10纳秒(近似)的时间区间内不会产生重复值。
为了缩减长度,对字符串做了 Base62处理。在处理前又将纳秒数值做了一次翻转处理。不难想象,如果直接使用原始值来做Base62处理,因为时钟的特征,最终生成的值的前几位都是相同的。
来看一下这个程序生成的ID:
aSPog4cC
d4t1xZdt
g2tkZVqv
jrinwXx5
m8ZIAKVr
oUB5nzS5
rZa1gPAl
uD12VZ3A
8dnItkTj
八位的长度,唯一且整齐。下面是一个单元测试:
@Test
public void gen() {
int size = 10240;
Set<String> set = new HashSet<>();
for (int i = 0; i < size; i++) {
String code = ShortCode.gen();
//System.out.println(code);
set.add(code);
}
Assert.assertEquals(size, set.size());
}
这里只对10240的规模做了测试。因为唯一ID是基于时钟生成的,所以测试时整体规模的大小不影响ID的唯一性(和短链接方案不一样)。但是太小了也不行——顺序号会发挥作用。10240算是一个中庸的值,足够暴露问题,也不会有太多的冗余。
仍然需要强调一下:这个方案只能保证在(当前)单机上的唯一性,如果是集群范围内建议采用其他方案,或者加上一两位机器ID。
总结
代码知识SEO上一篇 : js禁止查看源文件屏蔽Ctrl+u/s、F12、右键等兼容IE火狐chrome
下一篇 : 短网址的原理与生成方法(Java实现)
-
SEO外包最佳选择国内专业的白帽SEO机构,熟知搜索算法,各行业企业站优化策略!
SEO公司
-
可定制SEO优化套餐基于整站优化与品牌搜索展现,定制个性化营销推广方案!
SEO套餐
-
SEO入门教程多年积累SEO实战案例,从新手到专家,从入门到精通,海量的SEO学习资料!
SEO教程
-
SEO项目资源高质量SEO项目资源,稀缺性外链,优质文案代写,老域名提权,云主机相关配置折扣!
SEO资源
-
SEO快速建站快速搭建符合搜索引擎友好的企业网站,协助备案,域名选择,服务器配置等相关服务!
SEO建站
-
快速搜索引擎优化建议没有任何SEO机构,可以承诺搜索引擎排名的具体位置,如果有,那么请您多注意!专业的SEO机构,一般情况下只能确保目标关键词进入到首页或者前几页,如果您有相关问题,欢迎咨询!