Java 与文件getAbsolutePath()的争用条件

Java 与文件getAbsolutePath()的争用条件,java,multithreading,file,race-condition,Java,Multithreading,File,Race Condition,当我在Java程序中调用file.getAbsolutePath()时,似乎有一个竞争条件 在一个线程中,我正在处理一个文件,处理完毕后,我将更改文件名并将其移动到UNIX文件系统上的另一个目录 在并行运行的单独线程中,我试图打开正在处理的文件并读取其内容。在99%的用例中,这个操作是可以的,但是我注意到有时候操作会失败,出现FileNotFound异常 当我捕获此异常时,我正在记录文件.getAbsolutePath()值,我看到该值是已处理目录中的文件路径及其在处理完成前所在目录中的文件路径

当我在Java程序中调用
file.getAbsolutePath()
时,似乎有一个竞争条件

在一个线程中,我正在处理一个文件,处理完毕后,我将更改文件名并将其移动到UNIX文件系统上的另一个目录

在并行运行的单独线程中,我试图打开正在处理的文件并读取其内容。在99%的用例中,这个操作是可以的,但是我注意到有时候操作会失败,出现
FileNotFound
异常

当我捕获此异常时,我正在记录
文件.getAbsolutePath()
值,我看到该值是已处理目录中的文件路径及其在处理完成前所在目录中的文件路径的串联

过去有没有人遇到过类似的问题?你是如何解决的


谢谢

您似乎需要使用一个类来同步来自不同线程的文件访问,我们称之为
FileManager

实现
文件管理器的第一个选项是使用独占锁。例如:

class FileManager {

   private Object lock = new Object();

   public void processFile() {
       synchronized(lock) {
            ...
       }
   }

   public void readFile() {
      synchronized(lock) {
            ...
      }  
   }
}
如果读卡器比写卡器多,则读/写锁更合适,因为它允许多个并发读卡器,但只允许一个写卡器:

class FileManager {

   private final Lock readLock;
   private final Lock writeLock;

   FileManager() {
       ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(false);
       readLock = readWriteLock.readLock();
       writeLock = readWriteLock.writeLock();
   }

   public void processFile() {
       writeLock.lock();

       try {
            ...
       }
       finally {
          writeLock.unlock();
       }
   }

   public void readFile() {
       readLock.lock();

       try {
            ...
       }
       finally {
          readLock.unlock();
       } 
   }
}

没有人能知道你的问题是什么,只有这么少的信息。您似乎已经确定这是对getAbsolutePath()的调用,但我们没有证据证明这一点,而且它导致任何竞争条件的可能性要比您犯编程错误的可能性小得多。@JoshDavies注意到该文件未声明为线程安全,因此,如果没有适当的同步,您不能在线程之间共享它。您可以编写一个简短的程序来演示这个问题吗?(见附件)