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

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

精美图片:

  • 我没有使用RDBMS,所以我没有任何花哨的序列生成器(例如Oracle提供的序列生成器)
  • 我希望它快速,最好是所有内存 - 我宁愿不必打开一个文件并增加一些价值
  • 它需要是线程安全的(我预计一次只有一个JVM需要生成ID)
  • 需要在JVM的实例化之间保持一致。 如果服务器关闭并启动,那么ID生成器不应重新生成它在先前实例化中生成的相同ID(或者至少机会必须非常小,真正渺茫 - 我预计会有数百万的预设资源)
  • 我已经看到EJB唯一ID模式文章中的例子。 他们不会为我工作(我宁愿不单纯依靠System.currentTimeMillis(),因为我们将每毫秒保持多个资源)。
  • 我看了这个问题中提出的答案。 我对他们的关注是,随着时间的推移,我有可能获得重复ID的机会是多少? 我对使用java.util.UUID作为UUID的建议很感兴趣,但同样重复的机会需要无限小。
  • 我正在使用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年或4点nBits。

    链接地址: http://www.djcxy.com/p/91477.html

    上一篇: Generating a globally unique identifier in Java

    下一篇: Store UUID v4 in MySQL