簡體   English   中英

java.io.File.createNewFile()是否在網絡文件系統中是原子的?

[英]Is java.io.File.createNewFile() atomic in a network file system?

編輯:嗯,我回來了幾個月后,我試圖編碼的鎖機制不起作用,因為createNewFile在NFS上不可靠。 檢查下面的答案。


這是我的情況:我只有一個可以訪問文件的應用程序,因此我對其他應用程序可能執行的操作沒有任何限制,但是為了冗余和性能目的,應用程序在生產環境中的多個服務器上同時運行(有幾台機器正在使用我們的應用程序托管每個JVM。

基本上,我需要的是在文件夾中放置某種標志,以告訴其他實例單獨保留此文件夾,因為另一個實例已經在處理它。


許多搜索結果都告訴我們使用FileLock來實現這一目標,但是我檢查了Javadoc,根據我的理解它不會有太大幫助,因為它使用托管操作系統的鎖定可能性。 所以我懷疑它會有很大幫助,因為有不同的托管機器。

這個問題涵蓋了一個類似的主題: 網絡上的Java文件鎖定 ,並且接受的答案是建議實現您自己的協作鎖定過程(使用OP提出的File.createNewFile() )。


File.createNewFile()的Javadoc表示如果該文件尚不存在,該過程將自動創建該文件。 這在網絡文件系統中是否可靠?

我的意思是,潛在的網絡延遲如何同時進行存在檢查和創建?

檢查文件是否存在以及文件的創建(如果不存在)是針對可能影響文件的所有其他文件系統活動的原子操作。

不, createNewFile在網絡文件系統上無法正常工作。

即使系統調用是原子的,它只是關於操作系統的原子,而不是通過網絡。 隨着時間的推移,我遇到了幾次碰撞,比如每2-3個月一次(大約每600k文件一次)。

發生的事情是我的程序在2個獨立的服務器上運行6個實例,所以讓我們稱它們為A1,A2,A3和B1,B2,B3。
當A1,A2和A3嘗試創建相同的文件時,操作系統可以正確地確保只創建一個文件,因為它正在使用它自己。
當A1和B1嘗試在同一時刻創建相同的文件時,會出現某種形式的網絡緩存和/或網絡延遲,並且它們都從File.createNewFile()獲得true返回。
然后我的代碼通過重命名父文件夾來停止程序的其他實例,從而不必要地嘗試處理文件夾,這就是它失敗的地方:

  • 在A1上,文件夾重命名操作成功,但無法刪除鎖定文件,因此A1只是讓它這樣,並繼續處理新的傳入文件夾。
  • 在B1上,文件夾重命名操作( File.renameTo() ,無法修復它)陷入無限循環,因為文件夾已經重命名(根據我的系統管理員也導致巨大的I / O流量),在重新啟動程序之前,B1無法處理任何新文件。

檢查文件是否存在以及文件的創建(如果不存在)是針對可能影響文件的所有其他文件系統活動的原子操作。

這可以通過open()系統調用或我曾經使用過的任何操作系統中的等價物輕松實現。

我的意思是,潛在的網絡延遲如何同時進行存在檢查和創建?

同時原子之間存在差異。 Java doc並沒有說這個函數是一組兩個同步動作,而是兩個旨在以原子方式工作的動作。 如果構建此方法以原子方式執行兩個操作而不是在沒有先檢查文件存在的情況下永遠不會創建文件,並且如果文件由當前調用創建,則表示沒有文件存在且文件未創建意味着存在已經是該名稱的文件。

盡管呼叫在網絡或本地磁盤上,但我沒有理由懷疑功能是原子的還是可靠的。 本地呼叫同樣不可靠 - 在IO中可能出現很多問題。

當你嘗試使用這個函數創建的空文件作為Lock時,你不得不懷疑這是D-Mac對這個問題的回答, 也是Java Doc中為這個函數明確提到的。

你正在尋找一個目錄鎖和空文件作為目錄鎖(以指示其他進程和線程不接觸它)已經很好地為我工作提供了應當小心寫邏輯來檢查文件是否存在,鎖定文件清理向上和孤立的鎖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM