3 回答

TA貢獻(xiàn)1735條經(jīng)驗(yàn) 獲得超5個(gè)贊
UUID
128 位?UUID正是為您的目的而發(fā)明的:在一臺或多臺機(jī)器上生成標(biāo)識符,而無需通過中央機(jī)構(gòu)進(jìn)行協(xié)調(diào)。
理想情況下,您將使用原始版本 1 UUID,或其在版本 2、3 和 5 中的變體。原始版本采用主機(jī)網(wǎng)絡(luò)接口的 MAC 地址,并將其與當(dāng)前時(shí)刻加上一個(gè)小的任意數(shù)字相結(jié)合,該數(shù)字在主機(jī)時(shí)鐘已調(diào)整。這種方法消除了對重復(fù)項(xiàng)的任何實(shí)際關(guān)注。
Java 不捆綁生成這些版本的實(shí)現(xiàn)。我認(rèn)為 Java 設(shè)計(jì)者對泄露地點(diǎn)、時(shí)間和 MAC 地址有隱私和安全方面的擔(dān)憂。
Java 僅針對版本 4 提供了一種生成器實(shí)現(xiàn)。在這種類型中,128 位中除了 6 位之外的所有位都是隨機(jī)生成的。如果使用加密強(qiáng)隨機(jī)生成器,則此版本足以在大多數(shù)常見情況下使用而無需擔(dān)心沖突。
要知道 122 位是一個(gè)非常大的數(shù)字范圍 (5.316911983139664e+36)。64 位產(chǎn)生的范圍為 18,446,744,073,709,552,000(18 quintillion)。剩余的 58 位 (122-64=58) 產(chǎn)生的數(shù)字范圍為 288,230,376,151,711,740(288 千萬億)。現(xiàn)在將這兩個(gè)數(shù)字相乘得到 122 位的范圍:2^122 = ( 18,446,744,073,709,552,000 * 288,230,376,151,711,740 ) 即 5.3十進(jìn)制。
但是,如果您有權(quán)生成 4 以外的 UUID 版本,請接受它。例如,在Postgres等數(shù)據(jù)庫系統(tǒng)中,數(shù)據(jù)庫服務(wù)器可以在包括版本 1 在內(nèi)的各種版本中生成 UUID 編號?;蛘吣赡軙业接糜谏纱祟?UUID 的 Java 庫,盡管該庫可能不是平臺獨(dú)立的(它可能具有內(nèi)的本機(jī)代碼)。
System.nanoTime
明確這與當(dāng)前日期和時(shí)間無關(guān)System.nanoTime
。引用 Javadoc:
此方法只能用于測量經(jīng)過的時(shí)間,與系統(tǒng)或掛鐘時(shí)間的任何其他概念無關(guān)。
該System.nanoTime
功能僅返回一個(gè)數(shù)字,即自某個(gè)long
來源以來的納秒計(jì)數(shù),但未指定該來源。
Java 規(guī)范中唯一的承諾是源在 JVM 運(yùn)行期間不會改變。所以你知道這個(gè)數(shù)字在你的應(yīng)用程序執(zhí)行期間不斷增加。除非達(dá)到a 的限制long
,否則計(jì)數(shù)器將翻轉(zhuǎn)。如果原點(diǎn)為零,則翻轉(zhuǎn)可能需要 292 年(2^63 納秒)——但同樣,原點(diǎn)未指定。
根據(jù)我使用過的特定 Java 實(shí)現(xiàn)的經(jīng)驗(yàn),起源是 JVM 啟動的時(shí)刻。這意味著在下一次 JVM 重新啟動后,我肯定會再次看到相同的數(shù)字。
所以用作System.nanoTime
標(biāo)識符是一個(gè)糟糕的選擇。您的應(yīng)用程序是否碰巧達(dá)到了與之前運(yùn)行時(shí)完全相同的納秒數(shù),這純屬偶然,但您不必冒這個(gè)險(xiǎn)。請改用 UUID。

TA貢獻(xiàn)1812條經(jīng)驗(yàn) 獲得超5個(gè)贊
java.util.UUID.randomUUID()可能是線程安全的。
比較不同線程之間System.nanoTime()調(diào)用的結(jié)果是不安全的。如果許多線程在同一毫秒內(nèi)運(yùn)行,則此函數(shù)返回相同的毫秒數(shù)。
System.currentTimeMillis()也是如此。
比較 System.currentTimeMillis() 和 System.nanoTime(),后者更昂貴,因?yàn)樗枰嗟?cpu 周期,但也更準(zhǔn)確。所以 UUID 應(yīng)該符合你的目的。

TA貢獻(xiàn)1834條經(jīng)驗(yàn) 獲得超8個(gè)贊
我想是的,你可以使用System.nanoTime()
as id
。我已經(jīng)對其進(jìn)行了測試并且沒有遇到重復(fù)。 PS 但我強(qiáng)烈建議您使用 UUID。
添加回答
舉報(bào)