6

我想为我的应用程序中发生的事件生成 ID。

事件频率取决于用户负载,因此每秒可能发生数十万次。

我负担不起使用UUID.randomUUID(),因为它可能在性能问题上存在问题 - 看看这个

我想到了如下生成ID:

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

我的班级什么时候_random是静态的。java.util.Random

我的问题是:

  1. 您认为这种组合的分布是否足以满足我的需求?
  2. Java 的 Random 实现是否与当前时间相关,因此我将两者结合的事实是否危险?
4

4 回答 4

7

我会使用以下内容。

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 年里,我已经改用纳秒挂钟和内存映射文件来确保同一台机器上的进程之间的唯一性。代码可在此处获得。https://github.com/OpenHFT/Chronicle-Bytes/blob/ea/src/main/java/net/openhft/chronicle/bytes/MappedUniqueTimeProvider.java

于 2013-05-13T09:36:45.810 回答
3

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

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

或者您可以_random为使用用户 id 作为其种子的每个用户单独使用。

于 2013-05-13T09:16:47.363 回答
2

我负担不起使用 UUID.randomUUID() 因为它可能有问题

它可能不会。目前,您正在解决一个可能不存在的问题。我建议使用一个界面,这样您就可以轻松地更换生成的 ID,但要坚持使用这个生成器,许多聪明的人已经花了很多时间来使它正确。

您自己的解决方案可能在许多情况下都有效,但极端情况很重要,您只有在几年的经验后才能看到这些情况。

也就是说,结合当前时间 +Random应该会给出非常独特的 ID。但它们很容易被猜测和不安全。

于 2013-05-13T09:20:35.737 回答
2

UUID uuid = UUID.randomUUID();在预热后,慢了不到 8 倍,0.015 毫秒,而我的电脑上的 0.0021 毫秒。这对 UUID 来说是一个积极的论据——对我来说。

  1. 可以将随机数向右移动一点,因此时间更规范,排序。
  2. 不,涉及伪随机分布。
于 2013-05-13T09:19:38.200 回答