1. 程式人生 > >生成隨機id對比

生成隨機id對比

生成隨機id

最近公司的專案遊戲生成的隨機不重複id,重複概率有點大,

程式碼如下:

 1     private static int id = 0;
 2     public static int serverID = 0;
 3     private static final Object obj = new Object();
 4 
 5     public static long getId1() {
 6         synchronized (obj) {
 7             id += 1;
 8             return (serverID & 0xFFFF) << 48 | (System.currentTimeMillis() / 1000L & 0xFFFFFFFF) << 16 | id & 0xFFFF;
9 } 10 }

我做了一個性能測試

測試程式碼如下

 1     public static void main(String[] args) {
 2         HashSet<Long> longs = new HashSet<>();
 3         int lcount = 0;
 4         long starts = System.currentTimeMillis();
 5         int fcount = 100000;
 6         for (int i = 0; i < fcount; i++) {
7 long id = getId1(); 8 // long id = getId2(); 9 if (!longs.add(id)) { 10 lcount++; 11 } 12 } 13 long stops = System.currentTimeMillis(); 14 System.out.println("生產次數:" + fcount + " 成功生產次數:" + longs.size() + " 重複次數:" + lcount + " 耗時: " + (stops - starts));
15 }

測試生成次數和時間,

生產次數:100000 成功生產次數:65536 重複次數:34464 耗時: 18

經過測試,這段程式碼支援99999組伺服器同時生成id,保證不重複,但是前提條件是每一秒生成次數不超過65536個,
而且在不同伺服器產生重複概率還是有點高,
優點就是生產速度快,重複概率相對較低。
缺點就是每一秒生成的數量有限,
且不同伺服器id會產生相同的id

我在園友的部落格裡面發現了另外一種方式

    public static long getId2() {
        String toString = UUID.randomUUID().toString();
        byte[] bytes = toString.getBytes();
        long num = 0;
        for (int ix = 0; ix < 8; ++ix) {
            num <<= 8;
            num |= (bytes[ix] & 0xff);
        }
        return num;
    }

根據uuid生成long型隨機數,重複概率極低

生產次數:100000 成功生產次數:99999 重複次數:1 耗時: 579

看看這個結果,重複概率極低,極低,但是耗時相對較長,但也還算是在接受範圍內。

這個耗時加上了hashset的判斷耗時。

如果拋開hashet判斷會減少100多毫秒的生成時間;