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

2022-09-04 06:19:41

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

答案 1

非常确定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.000000000006(6×10-11),相当于一年内产生几百万亿UUID并有一个重复的几率。换句话说,只有在接下来的100年里每秒产生10亿个UUID之后,只产生一个重复的概率就约为50%。如果地球上的每个人都拥有6亿个UUID,那么一个重复的概率将约为50%。

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


答案 2
public class UniqueID {
    private static long startTime = System.currentTimeMillis();
    private static long id;

    public static synchronized String getUniqueID() {
        return "id." + startTime + "." + id++;
    }
}