2014-01-11 59 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(); 
     } 
    } 
}