如何在java中生成增量标识符

Ank*_*hag 1 java

我的要求是不断接收需要写入文件的消息。每次收到新消息时,都需要将其写入单独的文件中。我想要的是生成一个唯一标识符以用作文件名。我也想保留消息的顺序。我的意思是,作为文件名生成的标识符应该始终是增量的。

我使用UUID.randomUUID()来生成文件名,但这种方法的问题是 UUID 只保证标识符的随机性,而不是增量。结果我丢失了文件的顺序(我希望首先生成的文件应该首先出现在列表中)。

已知方法

  1. 可以使用 System.currentTimeMillis() 但我可以在同一时间戳接收多条消息。

2.另一种方法可能是实现静态长值并在要创建文件时增加它并将长值用作文件名。但我不确定这种方法。此外,它似乎不是我的问题的正确解决方案。我认为可能有比这更好的解决方案。

如果有人可以建议我更好地解决这个问题,将不胜感激。

Mar*_*nik 5

如果您希望即使在服务器重新启动之间您的 id 值也均匀上升,那么您必须要么基于系统时间,要么使用一些精心设计的健壮逻辑来保留上次使用的 ID。请注意,单独实现健壮性并不难,但以高性能和可扩展的方式实现健壮性却很困难。

如果您还需要 id 在冗余服务器集群中的多个节点上是唯一的,那么您需要更复杂的逻辑,这肯定涉及所有框同步访问的持久存储。当然,要实现这种性能更难。

我能看到的最佳选择是拥有一个很长的 ID,以便为这些部分留出空间:

  1. System.currentTimeMillis 长期唯一性(跨重启);
  2. System.nanotime 粒度更细;
  3. 每个服务器节点的唯一 ID(以特定于平台的方式确定)。

该方法仍然必须记住最后生成的值并在重复的情况下重试。然而,它不必重试太多次,直到下一个nanoTime时钟滴答——它甚至可能忙着等待它。

没有第 3 点的代码草图(单节点实现):

private static long lastNanos;
public static synchronized String uniqueId() {
  for (;/*ever*/;) {
    final long n = System.nanoTime();
    if (n == lastNanos) continue;
    lastNanos = n;
    return "" + System.currentTimeMillis() + n;
  }
}
Run Code Online (Sandbox Code Playgroud)