一、認識UUID
UUID
維基百科,自由的百科全書
通用唯一識別碼 (Universally Unique Identifier, UUID) 是一個軟件建構的標准,亦為自由軟件基金會 (Open Software Foundation, OSF) 的組織在分布式計算環境 (Distributed Computing Environment, DCE) 領域的一部份。
UUID 的目的,是讓分布式系統中的所有元素,都能有唯一的辨識信息,而不需要通過中央控制端來做辨識信息的指定。如此一來,每個人都可以建立不與其它人沖突的 UUID。在這樣的情況下,就不需考慮數據庫建立時的名稱重復問題。目前最廣泛應用的 UUID,即是微軟的 Microsoft's Globally Unique Identifiers (GUIDs),而其他重要的應用,則有 Linux ext2/ext3 文件系統、LUKS 加密分區區、GNOME、KDE、Mac OS X 等等。另外我們也可以在 e2fsprogs 包中的 UUID 庫找到實現。
[編輯] 定義
一組 UUID,系由一串 16 字節(亦稱 16 字節,或 128 位)的16進位數字所構成,是故UUID理論上的總數為216 x 8=2128,約等於3.4 x 1038。也就是說若每奈秒產生1兆個UUID,要花100億年才會將所有UUID用完。
UUID的標准類型包含32個16進位數字,以連字號分為五段,形式為8-4-4-4-12的32個字符。示例;
550e8400-e29b-41d4-a716-446655440000
UUID 亦可刻意重復以表示同類。例如說微軟的COM中,所有組件皆必須實現出IUnknown接口,方法是產生一個代表IUnknown的UUID。無論是程序試圖訪問組件中的IUnknown接口,或是實現IUnknown接口的組件,只要IUnknown一被使用,皆會被參考至同一個 ID:00000000-0000-0000-C000-000000000046。
[編輯] 隨機UUID的重復機率
隨機產生的UUID(例如說由java.util.UUID類產生的)的128個位中,有122個位是隨機產生,4個位在此版本('Randomly generated UUID')被使用,還有2個在其變體('Leach-Salz')中被使用。利用生日悖論,可計算出兩筆UUID擁有相同值的機率約為
以下是以x=2122計算出n筆UUID後產生碰撞的機率:
n 機率
68,719,476,736 = 236 0.0000000000000004 (4 x 10-16)
2,199,023,255,552 = 241 0.0000000000004 (4 x 10-13)
70,368,744,177,664 = 246 0.0000000004 (4 x 10-10)
與被隕石擊中的機率比較的話,已知一個人每年被隕石擊中的機率估計為170億分之1[1],也就是說機率大約是0.00000000006 (6 x 10-11),等同於在一年內置立數十兆筆UUID並發生一次重復。換句話說,每秒產生10億筆UUID,100年後只產生一次重復的機率是50%。如果地球上每個人都各有6億筆UUID,發生一次重復的機率是50%。
產生重復UUID並造成錯誤的情況非常低,是故大可不必考慮此問題。
機率也與亂數產生器的品質有關。若要避免重復機率提高,必須要使用奠基於密碼學上的假亂數產生器來生成值才行。
http://zh.wikipedia.org/zh-cn/UUID
二、Java5的UUID
在Java5以後,UUID的生成成了小菜一碟的小事,直接生成即可。對此需要了解:
有 4 種不同的基本 UUID 類型:基於時間的 UUID、DCE 安全 UUID、基於名稱的 UUID 和隨機生成的 UUID。 這些類型的 version 值分別為 1、2、3 和 4。具體什麼含義,看看JDK文檔即可。
這裡,主要想通過多線程生成UUID測試下,看看是否會重復,效率如何:
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Java的UUID生成工具並發測試
*
* @author leizhimin 2010-7-10 16:25:13
*/
public class TestUUID implements Runnable {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(5);
for (int i = 0; i < 8; i++) {
pool.execute(new TestUUID());
}
pool.shutdown();
}
public static String genReqID() {
// return UUID.randomUUID().toString().replace("-", "").toUpperCase();
return UUID.randomUUID().toString().toUpperCase();
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(genReqID());
}
}
}
20F644DE-23C5-4E04-BE38-991710D2DA13
93349C44-D8BA-495E-A687-44AE3FAEA9A5
BEB86A25-A9E5-47DC-BC22-157E021EAD3C
C990218F-C925-4A41-8006-D4489145CED6
767CD9B4-4E6A-4D53-BE96-CF35E6F69D60
A3876D8D-E807-492E-9054-28B9289EB5C5
17DD2BCD-E710-4F7A-B8F3-6BB19201E15B
901CCE61-4E47-4B2B-AA06-22A023D78313
81473B2F-FBC1-4D3D-834E-DEFFBD3C510C
46980DBD-E6A0-46E6-8FE9-E2E5766C2442
0BF83A5F-7A31-44C2-AE7F-EB4281F9CDE0
E35383D0-4850-45A1-B764-F8760BF1707B
772A2E21-ABAF-47AE-978C-AF70F40313F1
0DB815CF-C7B5-4E2F-B2DB-E84BC7B616F8
C826D9B7-E1F3-4F8E-8AAF-A61197AAFCCF
26CF2391-7C01-43FE-B515-5BD5DA6AF0B3
2544396E-D9C3-4D4D-B2CB-2A77107D4167
5BED5394-59DA-4E45-8182-34A24E1D2AC2
F32F5F1E-6C6F-4C9F-9944-6CE4EC8768F7
775F0B36-0965-4BA8-B1AA-FD1CFBE2B718
32DA0548-B562-444D-A16A-7E535EAA3C93
C935101E-7365-45C5-BBD1-3A64F2EC33C2
E623EC45-1F7E-4973-8132-424C134C7096
86AFEE47-AFD7-4479-B30D-0C2632087404
847F46FA-D112-4CB7-86E4-640F03A1E676
FA45ADA6-6A63-4961-B7C5-9501B21E116A
3E21CBC8-C116-437A-BAEC-4AD02F711F02
6025C077-379D-4458-BBEB-66D47FCF2206
09F7872D-90EE-4151-9463-1609200CE615
5FB07DF6-BA89-4017-BE9D-592DB6EADF05
6D7627AD-347C-4E69-B0A7-3674CCBDEE79
1E4E5E7D-AE3F-419F-836E-F284842261A6
1FFD670E-EC2C-462A-8E82-DACC21CF153A
FB5868EE-5330-4F6D-8CEE-0B1A50156E26
A38918F7-FB35-4560-9810-BE0B649E8D20
009508E8-0C9B-4189-BB5F-159F7EB2AAB6
30132165-0207-40B0-943F-E34B401D724F
CA5D15A0-490B-47D7-BF2A-9D58F8742E5B
BCE31255-156D-479E-B4EC-949A731B3FF2
A6CC370E-AFE0-439A-AFF3-37A76687B259
27894607-1CEF-43C2-93FC-75B59CB617A9
39ABD92B-D4CE-4B3C-BB70-D94739849DA2
04D2E913-75C2-4506-8ED7-5A95F023DCFD
FE853E35-72C6-422C-A7C4-CC4C0A4C9A98
7A6D6722-BC13-4965-95D4-F35B428E297D
92A4831A-A60E-4C16-AD8F-C8AC839436FF
9B58249F-3F6F-4434-ACF6-00F51A971243
7DDB1ABC-7918-4465-B8E3-0CB59D63F979
EF43F137-63D1-4361-BFB6-4A5C51B86C12
B785B7FE-FBA4-49B1-ADF8-CFD6107D9DB6
68EA68F7-A56B-4DDA-A832-BCD59BF67BA1
09F7E3E5-4344-49F7-992B-0E0B33D11296
78EEBA04-C836-44ED-829F-6F55E3E758A4
A4333A46-482B-47BE-87D0-BC0666EAE8FC
38E1212E-3D11-4275-A50C-42D98CEF91C5
FD9EDACF-6345-435E-B8A2-D8CDA8A66EE0
24925FA8-BB81-4639-BFFA-A12CA99E419F
B6994147-4AC2-414C-9669-9DC3E4BE8F88
1938E265-B213-46AC-A349-678B7E029771
485757B6-7C6E-4CFF-959B-6DF94DC282B6
C43E385D-B798-4FE0-8F50-2DCC8370655E
19426A29-E2C9-4DAF-A5EE-48131D719D66
8773F8F0-45C5-463B-85EB-97E8395CBB81
2B5F6CB2-E1F2-44A8-A60E-C8CD4191EE52
65775AF5-34C6-491A-8DED-A257E2480C62
A6F23801-B2E2-40A4-9415-43797BF14DD8
D1E386E3-6BBF-40E0-BF84-E0C41F32B6E7
97A836A3-64F9-4FDA-AD78-238CF1B8F413
32CE9D3D-EDA1-4E8C-87B9-DBAAD389FBAA
F2467331-CC34-49C1-9A3B-7566AE525B3B
847C08A3-D8AE-4C66-84F7-28387AD84EA9
5E8A99E6-600E-4797-B590-72345106E295
6B576614-4F9D-4018-98A8-ECCFDEA045B0
27070E60-ACE5-474D-AA47-8A4F37D16742
18BB8499-7836-4ACC-A301-167D52AB3D3F
8EC342B2-555A-4EAC-A82D-5AC6C7941421
5BF92378-7EFD-4454-806C-DFBFE51753C3
1A5B0717-07C0-46EA-8F3D-6246C57D9FB1
C3C642CE-A05E-496D-85E6-4830CF39970B
74B751BF-5CA5-4526-AFB8-2AA467852976
Process finished with exit code 0
本來UUID是小寫的,我改為大寫的了。可以發現一個規律,UUID碼是長度相同的,36位字符,如果去掉連接線,正好是32位的。其實完全可以去掉連接線,因為連接線的位置是相同的。
去掉的方法很簡單:
return UUID.randomUUID().toString().replace("-", "").toUpperCase();
通過上面測試,多線程下,UUID生成速度還是很快的。
出處http://lavasoft.blog.51cto.com/62575/347354