我可以使用 nanoTime 而不是 randomUUID 吗?

我正在编写一个每隔几秒向订阅者返回数据的过程。我想为订阅者创建一个唯一的 ID:

producer -> subsriber1
         -> subsriber2

使用有什么区别:

  • java.util.UUID.randomUUID()

  • System.nanoTime()

  • System.currentTimeMillis()

纳米时间会永远独一无二吗?随机UUID怎么样?


qq_花开花谢_0
浏览 137回答 3
3回答

喵喔喔

UUID128 位 UUID正是为您的目的而发明的:在一台或多台机器上生成标识符,而无需通过中央机构进行协调。理想情况下,您将使用原始版本 1 UUID,或其在版本 2、3 和 5 中的变体。原始版本采用主机网络接口的 MAC 地址,并将其与当前时刻加上一个小的任意数字相结合,该数字在主机时钟已调整。这种方法消除了对重复项的任何实际关注。Java 不捆绑生成这些版本的实现。我认为 Java 设计者对泄露地点、时间和 MAC 地址有隐私和安全方面的担忧。Java 仅针对版本 4 提供了一种生成器实现。在这种类型中,128 位中除了 6 位之外的所有位都是随机生成的。如果使用加密强随机生成器,则此版本足以在大多数常见情况下使用而无需担心冲突。要知道 122 位是一个非常大的数字范围 (5.316911983139664e+36)。64 位产生的范围为 18,446,744,073,709,552,000(18 quintillion)。剩余的 58 位 (122-64=58) 产生的数字范围为 288,230,376,151,711,740(288 千万亿)。现在将这两个数字相乘得到 122 位的范围:2^122 = ( 18,446,744,073,709,552,000 * 288,230,376,151,711,740 ) 即 5.3十进制。但是,如果您有权生成 4 以外的 UUID 版本,请接受它。例如,在Postgres等数据库系统中,数据库服务器可以在包括版本 1 在内的各种版本中生成 UUID 编号。或者您可能会找到用于生成此类 UUID 的 Java 库,尽管该库可能不是平台独立的(它可能具有内的本机代码)。System.nanoTime明确这与当前日期和时间无关System.nanoTime。引用 Javadoc:此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关。该System.nanoTime功能仅返回一个数字,即自某个long来源以来的纳秒计数,但未指定该来源。Java 规范中唯一的承诺是源在 JVM 运行期间不会改变。所以你知道这个数字在你的应用程序执行期间不断增加。除非达到a 的限制long,否则计数器将翻转。如果原点为零,则翻转可能需要 292 年(2^63 纳秒)——但同样,原点未指定。根据我使用过的特定 Java 实现的经验,起源是 JVM 启动的时刻。这意味着在下一次 JVM 重新启动后,我肯定会再次看到相同的数字。所以用作System.nanoTime标识符是一个糟糕的选择。您的应用程序是否碰巧达到了与之前运行时完全相同的纳秒数,这纯属偶然,但您不必冒这个险。请改用 UUID。

ABOUTYOU

java.util.UUID.randomUUID()可能是线程安全的。比较不同线程之间System.nanoTime()调用的结果是不安全的。如果许多线程在同一毫秒内运行,则此函数返回相同的毫秒数。System.currentTimeMillis()也是如此。比较 System.currentTimeMillis() 和 System.nanoTime(),后者更昂贵,因为它需要更多的 cpu 周期,但也更准确。所以 UUID 应该符合你的目的。

MMMHUHU

我想是的,你可以使用System.nanoTime()as id。我已经对其进行了测试并且没有遇到重复。 PS 但我强烈建议您使用 UUID。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java