我的程序需要生成由标签、日期和时间组成的唯一标签。像这样的东西:
"myTag__2019_09_05__07_51"
Run Code Online (Sandbox Code Playgroud)
如果一个人试图在同一分钟内生成两个具有相同标签的标签,一个人将收到相同的标签,这是我不能允许的。我考虑添加作为 System.nanoTime() 的附加后缀结果,以确保每个标签都是唯一的(我无法访问之前生成的所有标签来查找重复项):
"myTag__2019_09_05__07_51__{System.nanoTime() result}"
Run Code Online (Sandbox Code Playgroud)
我可以相信每次调用 System.nanoTime() 都会产生不同的值吗?我在我的笔记本电脑上进行了这样的测试:
assertNotEquals(System.nanoTime(), System.nanoTime())
Run Code Online (Sandbox Code Playgroud)
这有效。我想知道我是否能保证它永远有效。
太长了;如果您仅在现代操作系统上的流行虚拟机上使用单线程,那么它在实践中可能会起作用。但许多严肃的应用程序使用多个线程和应用程序的多个实例,在这种情况下不会有任何保证。
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");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
此外,当您将应用程序扩展到多台计算机时,您可能会遇到同样的问题。
依靠System.nanoTime()
获得独特的价值观并不是一个好主意。
归档时间: |
|
查看次数: |
1103 次 |
最近记录: |