System.nanoTime()是否保证返回唯一值?

时间:2013-03-19 07:24:14

标签: java file time temporary-files

我有一个多线程Java程序,可以在几秒钟内创建数百个临时文件。这些文件放在/tmp中,并使用System.nanoTime()命名。

文件名是否保证唯一?

4 个答案:

答案 0 :(得分:18)

不,无法保证每次拨打System.nanoTime()都会返回唯一值。

改为使用File.createTempFile()Files.createTempFile()。它们专为此目的而设计,并将为您生成唯一的文件名。

答案 1 :(得分:3)

如果您需要临时文件的唯一文件名,请使用File.createTempFile(prefix, suffix, directory)

答案 2 :(得分:3)

至于你原来的问题

不,不是真的。您的线程可以在多CPU /核心系统上同时并行运行,因此无法保证唯一值。

另外,nanoTime()仅与底层时钟一样准确。这意味着,对nanoTime的两次连续调用可以返回相同的值。

来自API的引用:“不保证值的变化频率。”

解决方案

您应该使用File.createTempFile()并让Java处理临时文件的唯一性。

// create temp file in /tmp with prefix  tmpfile and suffix .txt
File file = File.createTempFile("tmpfile", ".txt", new File("/tmp"));

// deletes file when the virtual machine terminate
file.deleteOnExit();

您甚至可以使用线程ID或类似的前缀来保持这些temFiles appart。

答案 3 :(得分:1)

如果在每纳秒可以创建多个文件的计算机上运行线程系统,则可能/将发生名称冲突。

对此的解决方案可能是存储一个静态“索引计数器”,您可以使用它来预先添加/附加到文件名。

例如,您的文件名可能是System.nanoTime() + "x" + SomeClassName.index(),其中index()方法将返回索引的值,同时也会递增它。 (您可以通过index()返回String或将值转换为1来抛弃“x”。

每次程序重新启动时,“索引计数器”是否重置为0都没关系(我真的怀疑JVM实例可以在一纳秒内启动)。

确保index()方法是线程安全的。

编辑:

我的解决方案为您提供了一种生成唯一文件名的方法。我使用类似的解决方案(使用“System.currentTimeMillis()”而不是System.nanoTime())来为在数据库中具有临时表示的变量生成唯一ID,并且它像魅力一样工作(使用前缀,它也是允许批量删除DB中的某些条目,而不仅仅是清空DB)。

如果您对文件名本身不感兴趣,但只对使用/使用临时文件感兴趣,我会选择NPE的解决方案。