Java 未引发FileReadyExistsException,正在覆盖文件

Java 未引发FileReadyExistsException,正在覆盖文件,java,multithreading,file,io,Java,Multithreading,File,Io,此代码: File tmpFile = File.createTempFile(PREFIX_TMP, null, new File(reportPath)); logger.debug("The report will be saved in the temporary file '{}'", tmpFile.getName()); reportWriter.write(tmpFile, report); Calendar calendar

此代码:

File tmpFile = File.createTempFile(PREFIX_TMP, null, new File(reportPath));
        logger.debug("The report will be saved in the temporary file '{}'", tmpFile.getName());

        reportWriter.write(tmpFile, report);

        Calendar calendar = Calendar.getInstance();

        boolean isFileMoved = false;
        while (!isFileMoved) {
            String reportName = String.format(report.getName(), calendar.getTime());
            File reportFile = new File(reportPath, reportName);

            try {
                Files.move(tmpFile.toPath(), reportFile.toPath());
                isFileMoved = true;

                logger.info("The temporary file '{}' is renamed to '{}'", tmpFile.getName(), reportFile.getName());
            } catch (FileAlreadyExistsException e) {
                logger.warn("The file '{}' already exists in the folder '{}': adding a second to generation time",
                        reportName, reportPath);
            }

            calendar.add(Calendar.SECOND, 1);
        }
生成以下不可能的日志语句:

2016-10-04 10:35:11674[警告][u Executor-1]a.b.c.MyGenerator-发电机 文件夹中已存在文件“myFile_01092016103511.csv” “/myDir”:向生成时间添加第二个

2016-10-04 10:35:11677[警告][u Executor-3]a.b.c.MyGenerator-发电机 文件夹中已存在文件“myFile_01092016103511.csv” “/myDir”:向生成时间添加第二个

2016-10-04 10:35:11677[信息][u Executor-1]a.b.c.MyGenerator-我的发电机 临时文件“tmp2103892505851032137.tmp”重命名为 “myFile_01092016103512.csv”

2016-10-04 10:35:11680[信息][u Executor-3]a.b.c.MyGenerator-我的发电机 临时文件“tmp68436889692754506611.tmp”重命名为 “myFile_01092016103512.csv”

Executor 3会覆盖该文件,即使它会引发FileReadyExistsException


不会引发异常,并且文件的数据已被覆盖。

文件。move
使用
文件。内部存在,使用多个线程时,状态可能会在其间发生更改

执行器3会覆盖该文件,即使它会引发FileReadyExistsException

如果希望
文件.move(…)
以原子方式运行,则需要使用。默认情况下,它首先测试目标是否存在,然后执行易受影响的移动。以下是:

原子移动–作为原子文件操作执行移动。如果文件系统不支持原子移动,将引发异常。通过原子移动,您可以将文件移动到目录中,并保证任何监视目录的进程都可以访问完整的文件

如果必须支持
filereadyExistsException
功能,则需要使用
synchronized
块来保护移动,以便一次只允许一个线程运行它。如果您在该块中执行IO,
synchronized
应该很少甚至没有性能损失