我的程序需要生成包含标签,日期和时间的唯一标签。像这样:

"myTag__2019_09_05__07_51"


如果有人试图在同一分钟内生成两个带有相同标签的标签,那么一个人将获得相等的标签,这是我所不允许的。我想添加System.nanoTime()的附加后缀结果,以确保每个标签都是唯一的(我无法访问先前生成的所有标签以查找重复项):

"myTag__2019_09_05__07_51__{System.nanoTime() result}"


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

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


这可行。我想知道我是否可以保证始终有效。

最佳答案

TLDR;如果仅在现代操作系统上的流行VM上使用单个线程,则它可能会在实践中起作用。但是,许多严肃的应用程序使用多个线程和应用程序的多个实例,在这种情况下无法保证。

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

在我的OS(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()获得唯一值不是一个好主意。

关于java - 我可以相信System.nanoTime()每次调用都会返回不同的值吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57799193/

10-10 16:09