13

简介:我正在开发一个持久化的 Java Web 应用程序,我需要确保我持久化的所有资源都具有全局唯一标识符,以防止重复。

精美的印刷品:

  1. 我没有使用 RDBMS,所以我没有任何花哨的序列生成器(比如 Oracle 提供的那个)
  2. 我希望它很快,最好全部在内存中 - 我宁愿不必打开文件并增加一些值
  3. 它需要是线程安全的(我预计一次只有一个 JVM 需要生成 ID)
  4. JVM 实例之间需要保持一致性。如果服务器关闭并启动,ID 生成器不应重新生成它在先前实例化中生成的相同 ID(或者至少机会必须非常非常渺茫 - 我预计会有数百万的预置资源)
  5. 我已经看过 EJB 唯一 ID 模式文章中的示例。它们对我不起作用(我宁愿不完全依赖 System.currentTimeMillis() ,因为我们将每毫秒保留多个资源)。
  6. 我已经查看了这个问题中提出的答案。我对他们的担忧是,随着时间的推移,我获得重复 ID 的可能性有多大?我对使用java.util.UUID作为UUID的建议很感兴趣,但同样,重复的机会需要非常小。
  7. 我正在使用JDK6
4

6 回答 6

32

很确定UUID“足够好”。有 340,282,366,920,938,463,463,374,607,431,770,000,000 个 UUID 可用。

http://www.wilybeagle.com/guid_store/guid_explain.htm

“从这些数字来看,一个人每年被陨石击中的风险估计为 170 亿分之一,这意味着概率约为 0.00000000006 (6 × 10−11),相当于创造几个一年有几十万亿个UUID,并且有一个重复。也就是说,在接下来的100年每秒产生10亿个UUID之后,只创建一个重复的概率大约是50%。一个重复的概率是如果地球上每个人都拥有 6 亿个 UUID,则大约是 50%”

http://en.wikipedia.org/wiki/Universally_Unique_Identifier

于 2008-10-10T20:32:29.807 回答
1

如果它需要每台 PC 都是唯一的:您可能可以使用(System.currentTimeMillis() << 4) | (staticCounter++ & 15)或类似的东西。

这将允许您每毫秒生成 16 个。如果您需要更多,请移动 5,然后移动 31...

如果它需要在多台 PC 中是唯一的,您还应该结合主网卡的 MAC 地址。

编辑:澄清

private static int staticCounter=0;
private final int nBits=4;
public long getUnique() {
    return (currentTimeMillis() << nBits) | (staticCounter++ & 2^nBits-1);
}

并将 nBits 更改为您应该每毫秒生成的最大数的平方根。

它最终会翻身。可能需要 20 年左右,而 nBits 为 4。

于 2008-10-10T20:37:21.637 回答
1
public class UniqueID {
    private static long startTime = System.currentTimeMillis();
    private static long id;

    public static synchronized String getUniqueID() {
        return "id." + startTime + "." + id++;
    }
}
于 2008-10-13T08:25:04.920 回答
0

从内存中,RMI 远程包包含一个 UUID 生成器。我不知道这是否值得研究。

当我不得不生成它们时,我通常使用当前日期时间、用户名和计算机 IP 地址的 MD5 哈希和。基本上,这个想法是获取有关计算机/人的所有信息,然后生成此信息的 MD5 哈希。

它工作得非常好,而且速度非常快(一旦你第一次初始化 MessageDigest)。

于 2008-10-13T02:24:50.687 回答
0

为什么不这样做

String id = Long.toString(System.currentTimeMillis()) + 
    (new Random()).nextInt(1000) + 
    (new Random()).nextInt(1000);
于 2012-03-16T21:49:47.087 回答
0

如果您想使用 java UUID 的更短更快的实现,请查看:

https://code.google.com/p/spf4j/source/browse/trunk/spf4j-core/src/main/java/org/spf4j/concurrent/UIDGenerator.java

请参阅 javadoc 中的实现选择和限制。

这是一个关于如何使用的单元测试:

https://code.google.com/p/spf4j/source/browse/trunk/spf4j-core/src/test/java/org/spf4j/concurrent/UIDGeneratorTest.java

于 2014-09-30T03:57:40.750 回答