为了账号安全,请及时绑定邮箱和手机立即绑定

我可以相信 System.nanoTime() 每次调用都会返回不同的值吗?

我可以相信 System.nanoTime() 每次调用都会返回不同的值吗?

饮歌长啸 2023-07-13 17:39:06
我的程序需要生成由标签、日期和时间组成的唯一标签。像这样的东西:"myTag__2019_09_05__07_51"如果一个人试图在同一分钟内生成两个具有相同标签的标签,一个人将收到相同的标签,这是我不能允许的。我考虑添加作为 System.nanoTime() 的附加后缀结果,以确保每个标签都是唯一的(我无法访问之前生成的所有标签来查找重复项):"myTag__2019_09_05__07_51__{System.nanoTime() result}"我可以相信每次调用 System.nanoTime() 都会产生不同的值吗?我在我的笔记本电脑上进行了这样的测试:assertNotEquals(System.nanoTime(), System.nanoTime())这有效。我想知道我是否能保证它永远有效。
查看完整描述

1 回答

?
互换的青春

TA贡献1797条经验 获得超6个赞

太长了;如果您仅在现代操作系统上的流行虚拟机上使用单线程,那么它在实践中可能会起作用。但许多严肃的应用程序使用多个线程和应用程序的多个实例,在这种情况下不会有任何保证。

Javadoc中对 System.nanoTime() 给出的唯一保证是时钟的分辨率至少与System.currentTimeMillis()- 因此,如果您正在编写跨平台代码,显然不希望 的结果nanoTime是唯一的,因为每毫秒可以调用nanoTime()多次。

在我的操作系统(Java 11、MacOS)上,同一线程上的连续调用之间总是至少有一纳秒的差异(这是在 Integer.MAX_VALUE 查看连续返回值之后);实施中可能有一些东西可以保证这一点。

然而,如果您使用多个线程并且拥有超过 1 个物理 CPU,则很容易生成重复结果。下面的代码将向您展示:

public class UniqueNano {

    private static volatile long a = -1, b = -2;


    public static void main(String[] args) {

        long max = 1_000_000;

        new Thread(() -> {

            for (int i = 0; i < max; i++) { a = System.nanoTime(); }

        }).start();

        new Thread(() -> {

            for (int i = 0; i < max; i++) { b = System.nanoTime(); }

        }).start();

        for (int i = 0; i < max; i++) {

            if (a == b) {

                System.out.println("nanoTime not unique");

            }

        }

    }

}

此外,当您将应用程序扩展到多台计算机时,您可能会遇到同样的问题。


依靠System.nanoTime()获得独特的价值观并不是一个好主意。


查看完整回答
反对 回复 2023-07-13
  • 1 回答
  • 0 关注
  • 193 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信