【问题标题】:Is System.nanoTime() guaranteed to return unique values?System.nanoTime() 是否保证返回唯一值?
【发布时间】:2013-03-19 07:24:14
【问题描述】:

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

文件名是否保证唯一?

【问题讨论】:

  • 不总是,但很有可能。
  • @Andreas_D - 或者换句话说,两个生成的文件名相同的概率足够小,以至于不会在测试中被选中。索德定律说,问题会在生产中再次出现并困扰您。
  • 斯蒂芬,这就是我发表评论的意图。没有保证。对于唯一名称:使用序列。或者将随机数连接到 nano 值以进一步降低名称冲突的可能性。或者:只需检查文件是否存在并生成一个新名称,如果是这样的话。

标签: java file time temporary-files


【解决方案1】:

不,不能保证每次调用 System.nanoTime() 都会返回一个唯一值。

请改用File.createTempFile() 或Files.createTempFile()。它们就是为此目的而设计的,并且会为您生成唯一的文件名。

【讨论】:

  • 哦..真的吗??你能告诉我任何方法来代替它吗?干杯伙伴。
  • @DannyChoi: createTempFile(),如我的回答中所述。
  • 是的,我正在使用 ... temp = File.createTempFile("temp", Long.toString(System.nanoTime()));
  • 你不需要给createTempFile一个唯一的字符串;它应该为您创建。你可以简单地使用File.createTempFile("temp", null);
  • prefix 和 suffix 参数都只是 API 为您扩展的一种便利,因此您可以将唯一字符串放在文件名中的任何位置。
【解决方案2】:

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

【讨论】:

    【解决方案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 分开。

    【讨论】:

      【解决方案4】:

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

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

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

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

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

      编辑:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多