java唯一字符串ID生成方案詳解
工作中經(jīng)常會有生成唯一字符串的需求。通常最容易想到的是UUID。UUID的唯一性毋庸置疑,但是32位的長度也容易讓人退避三舍。也曾經(jīng)想過參考《短網(wǎng)址生成方案》來生成一串ID,但是試驗了一下發(fā)現(xiàn)唯一性不太好。
最終采用的方案是時鐘方案,簡單來說就是用當(dāng)前時間戳做唯一ID。
采用時間戳做ID,秒或毫秒都容易產(chǎn)生重復(fù),換成納秒在單節(jié)點上就沒問題了。參考百度百科關(guān)于納秒的描述就能清楚為什么納秒級別的時間戳不會產(chǎn)生重復(fù):
光在真空中一納秒僅傳播0.3米。個人電腦的微處理器執(zhí)行一道指令(如將兩數(shù)相加)約需2至4納秒。
我們生成一條唯一ID所需的CPU指令絕不止一道,因此用納秒作單機唯一ID是綽綽有余的。在測試中發(fā)現(xiàn),即使是千分之一納秒也足夠我們在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); }
這里用千分之一納秒做基數(shù)(經(jīng)測試,基數(shù)在10w分之一納秒內(nèi)都是安全的),再加上1~99的順序號來生成唯一ID。最終可以保證在大于10納秒(近似)的時間區(qū)間內(nèi)不會產(chǎn)生重復(fù)值。
為了縮減長度,對字符串做了 Base62處理。在處理前又將納秒數(shù)值做了一次翻轉(zhuǎn)處理。不難想象,如果直接使用原始值來做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的規(guī)模做了測試。因為唯一ID是基于時鐘生成的,所以測試時整體規(guī)模的大小不影響ID的唯一性(和短鏈接方案不一樣)。但是太小了也不行——順序號會發(fā)揮作用。10240算是一個中庸的值,足夠暴露問題,也不會有太多的冗余。
仍然需要強調(diào)一下:這個方案只能保證在(當(dāng)前)單機上的唯一性,如果是集群范圍內(nèi)建議采用其他方案,或者加上一兩位機器ID。
總結(jié)
到此這篇關(guān)于java唯一字符串ID生成方案的文章就介紹到這了,更多相關(guān)java唯一字符串ID生成內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaGUI界面實現(xiàn)頁面跳轉(zhuǎn)方法
這篇文章主要給大家介紹了關(guān)于JavaGUI界面實現(xiàn)頁面跳轉(zhuǎn)的相關(guān)資料, GUI是指圖形用戶界面,指采用圖形方式顯示的計算機操作用戶界面,需要的朋友可以參考下2023-07-07springmvc使用REST出現(xiàn):Request?method?'PUT'?not?sup
這篇文章主要介紹了springmvc使用REST出現(xiàn):Request?method?'PUT'?not?supported問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02關(guān)于IDEA報錯Error:java 不支持發(fā)行版本17的原因及解決方案
在rebuild或運行項目時提示“Error:java: 錯誤: 不支持發(fā)行版本 17”,本文將給大家介紹了IDEA提示“Error:java: 錯誤: 不支持發(fā)行版本17”的原因及解決方案,需要的朋友可以參考下2023-09-09