在Java中生成全局唯一标识符

简介:我正在开发一个持久的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

很确定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

public class UniqueID { private static long startTime = System.currentTimeMillis(); private static long id; public static synchronized String getUniqueID() { return "id." + startTime + "." + id++; } } 

如果它需要每台PC都是唯一的:你可以使用(System.currentTimeMillis() << 4) | (staticCounter++ & 15) (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更改为每ms应生成的最大数字的平方根。

它最终会翻身。 可能是20年或者nBits为4的东西。

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

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

它运行得非常好并且速度非常快(一旦你第一次初始化MessageDigest)。

为什么不这样做呢

 String id = Long.toString(System.currentTimeMillis()) + (new Random()).nextInt(1000) + (new Random()).nextInt(1000); 

如果你想使用java UUID看一下的更短更快的实现:

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

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

这是一个如何使用的unit testing:

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