java 快速生成ID,并具有较高的唯一性概率

ej83mcc0  于 2023-01-01  发布在  Java
关注(0)|答案(5)|浏览(162)

我想为应用程序中发生事件生成ID。
事件频率取决于用户负载,因此每秒可能发生数百万次。
我不能使用UUID.randomUUID(),因为它在性能方面可能会有问题-看看this
我认为生成ID如下所示:

System.currentTimeMillis() + ";" + Long.toString(_random.nextLong())

_random是一个静态java.util.Random时,我的类正在保存。
我的问题是:
1.你认为这个组合的分布能满足我的需要吗?

  1. Java的Random实现是否与当前时间有关,因此我将两者结合起来是危险的?
a9wyjsp7

a9wyjsp71#

我将使用以下内容。

final AtomicLong counter = new AtomicLong(System.currentTimeMillis() * 1000);

以及

long l = counter.getAndIncrement(); // takes less than 10 nano-seconds most of the time.

这在您的系统内和重启过程中是唯一的,前提是您的平均速度低于每秒一百万次。
即使以这样的速度,这个数字在一段时间内也不会溢出。

class Main {
    public static void main(String[] args) {
        System.out.println(new java.util.Date(Long.MAX_VALUE/1000));
    }
}

印刷品

Sun Jan 10 04:00:54 GMT 294247

编辑:在过去的8年里,我已经改用纳秒级的挂钟和内存Map文件来确保同一台机器上进程的唯一性。

lp0sw83n

lp0sw83n2#

为了防止可能的冲突,我建议您以某种方式将用户的唯一ID集成到生成的ID中。您可以将用户ID直接添加到生成的ID中

System.currentTimeMillis() + ";" + Long.toString(_random.nextLong()) + userId

也可以为每个用户使用单独的_random,并将用户的id用作种子。

t0ybt7op

t0ybt7op3#

UUID uuid = UUID.randomUUID();在预热后慢了不到8倍,为0.015毫秒,而我的PC为0.0021毫秒。这对UUID来说是一个积极的论点。
1.你可以把随机长的向右移动一点,这样时间就更规范,更有序了。
1.不,这是一个伪随机分布。

wrrgggsh

wrrgggsh4#

我不能使用UUID.randomUUID(),因为它可能会有问题
它可能不会。目前,你正在解决一个可能不存在的问题。我建议使用一个接口,这样你就可以很容易地交换出生成的ID,但坚持使用这个生成器,许多聪明的人花了很多时间来使它正确。
您自己的解决方案可能在许多情况下有效,但极端情况很重要,您只有在几年的经验后才会看到这些情况。
也就是说,将当前时间+ Random组合起来应该会给予非常唯一的ID,但是它们很容易被猜到,而且不安全。

ehxuflar

ehxuflar5#

我会使用图书馆来避免重复劳动。
例如,JUG(https://github.com/cowtowncoder/java-uuid-generator)每秒可以生成5百万个基于时间的UUID(https://github.com/cowtowncoder/java-uuid-generator/blob/master/release-notes/FAQ):

<dependency>
  <groupId>com.fasterxml.uuid</groupId>
  <artifactId>java-uuid-generator</artifactId>
  <version>4.0.1</version>
</dependency>

UUID uuid = Generators.timeBasedGenerator().generate();

相关问题