生成随机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多毫秒的生成时间;