2014-01-11 57 views
-1

当我在我的Java程序中调用file.getAbsolutePath()时,似乎我有竞争条件。与文件getAbsolutePath竞争条件()java

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

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

当我捕捉到这个异常时,我记录了file.getAbsolutePath()的值,我看到该值是文件在已经移动的已处理目录中的路径与它所在目录中文件的路径的连接出现在加工完成前。

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

感谢

+1

没有人能告诉你的问题在于信息太少。你似乎已经决定调用getAbsolutePath(),但是我们没有这方面的证据,并且它比导致编程错误的情况更不可能导致任何类型的竞争条件。 – arcy

+0

@JoshDavies请注意,File没有声明为线程安全的,所以您不能在没有正确同步的线程之间共享它。 – isnot2bad

+0

你能写一个简短的程序来证明这个问题吗? (见[SSCCE](http://sscce.org/)) – ntoskrnl

回答

0

看来你需要使用类,这是否从单独的线程文件访问同步,让我们称之为FileManager

执行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(); 
     } 
    } 
}