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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/192920/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:08:49  来源:igfitidea点击:

Generating a globally unique identifier in Java

javapersistenceuuiduniqueidentifier

提问by Julie

Summary:I'm developing a persistent Java web application, and I need to make sure that all resources I persist have globally unique identifiers to prevent duplicates.

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

The Fine Print:

精美印刷品:

  1. I'm not using an RDBMS, so I don't have any fancy sequence generators (such as the one provided by Oracle)
  2. I'd like it to be fast, preferably all in memory - I'd rather not have to open up a file and increment some value
  3. It needs to be thread safe (I'm anticipating that only one JVM at a time will need to generate IDs)
  4. There needs to be consistency across instantiations of the JVM. If the server shuts down and starts up, the ID generator shouldn't re-generate the same IDs it generated in previous instantiations (or at least the chance has to be really, really slim - I anticipate many millions of presisted resources)
  5. I have seen the examples in the EJB unique ID pattern article. They won't work for me (I'd rather not rely solely on System.currentTimeMillis() because we'll be persisting multiple resources per millisecond).
  6. I have looked at the answers proposed in this question. My concern about them is, what is the chance that I will get a duplicate ID over time? I'm intrigued by the suggestion to use java.util.UUIDfor a UUID, but again, the chances of a duplicate need to be infinitesimally small.
  7. I'm using JDK6
  1. 我没有使用 RDBMS,所以我没有任何花哨的序列生成器(例如 Oracle 提供的)
  2. 我希望它很快,最好全部在内存中 - 我宁愿不必打开文件并增加一些值
  3. 它需要是线程安全的(我预计一次只有一个 JVM 需要生成 ID)
  4. JVM 的实例化之间需要保持一致性。如果服务器关闭并启动,ID 生成器不应该重新生成它在先前实例中生成的相同 ID(或者至少机会必须非常非常渺茫——我预计会有数百万的预存资源)
  5. 我已经看过 EJB 唯一 ID 模式文章中的示例。它们对我不起作用(我宁愿不完全依赖 System.currentTimeMillis() 因为我们将每毫秒持久化多个资源)。
  6. 我看过这个问题中提出的答案。我对他们的担忧是,随着时间的推移,我获得重复 ID 的可能性有多大?我对使用java.util.UUID作为UUID的建议很感兴趣,但同样,重复的机会需要无限小。
  7. 我正在使用 JDK6

采纳答案by Shawn Miller

Pretty sure UUIDs are "good enough". There are 340,282,366,920,938,463,463,374,607,431,770,000,000 UUIDs available.

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

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

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

"To put these numbers into perspective, one's annual risk of being hit by a meteorite is estimated to be one chance in 17 billion, that means the probability is about 0.00000000006 (6 × 10?11), equivalent to the odds of creating a few tens of trillions of UUIDs in a year and having one duplicate. In other words, only after generating 1 billion UUIDs every second for the next 100 years, the probability of creating just one duplicate would be about 50%. The probability of one duplicate would be about 50% if every person on earth owns 600 million UUIDs"

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

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

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

回答by Bill K

If it needs to be unique per PC: you could probably use (System.currentTimeMillis() << 4) | (staticCounter++ & 15)or something like that.

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

That would allow you to generate 16 per ms. If you need more, shift by 5 and and it with 31...

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

if it needs to be unique across multiple PCs, you should also combine in your primary network card's MAC address.

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

edit: to clarify

编辑:澄清

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

and change nBits to the square root of the largest number you should need to generate per ms.

并将 nBits 更改为每毫秒需要生成的最大数字的平方根。

It will eventually roll over. Probably 20 years or something with nBits at 4.

它最终会翻车。nBits 为 4 时可能需要 20 年左右。

回答by Aidos

From memory the RMI remote packages contain a UUID generator. I don't know whether thats worth looking into.

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

When I've had to generate them I typically use a MD5 hashsum of the current date time, the user name and the IP address of the computer. Basically the idea is to take everything that you can find out about the computer/person and then generate a MD5 hash of this information.

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

It works really well and is incredibly fast (once you've initialised the MessageDigest for the first time).

它工作得非常好并且非常快(一旦您第一次初始化了 MessageDigest)。

回答by Dave Griffiths

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

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

回答by kem

why not do like this

为什么不这样做

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

回答by user2179737

if you want to use a shorter and faster implementation that java UUID take a look at:

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

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

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

see the implementation choices and limitations in the javadoc.

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

here is a unit test on how to use:

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

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

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