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

我的程序需要生成由标签、日期和时间组成的唯一标签。像这样的东西:

"myTag__2019_09_05__07_51"

如果一个人试图在同一分钟内生成两个具有相同标签的标签,一个人将收到相同的标签,这是我不能允许的。我考虑添加作为 System.nanoTime() 的附加后缀结果,以确保每个标签都是唯一的(我无法访问之前生成的所有标签来查找重复项):

"myTag__2019_09_05__07_51__{System.nanoTime() result}"

我可以相信每次调用 System.nanoTime() 都会产生不同的值吗?我在我的笔记本电脑上进行了这样的测试:

assertNotEquals(System.nanoTime(), System.nanoTime())

这有效。我想知道我是否能保证它永远有效。


饮歌长啸
浏览 194回答 1
1回答

互换的青春

太长了;如果您仅在现代操作系统上的流行虚拟机上使用单线程,那么它在实践中可能会起作用。但许多严肃的应用程序使用多个线程和应用程序的多个实例,在这种情况下不会有任何保证。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()获得独特的价值观并不是一个好主意。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java