1.1概述——文件鎖
?
文件鎖定初看起來可能讓人迷惑。它 似乎 指的是防止程序或者用戶訪問特定文件。事實上,文件鎖就像常規的?Java?對象鎖 — 它們是 勸告式的(advisory) 鎖。它們不阻止任何形式的數據訪問,相反,它們通過鎖的共享和獲取賴允許系統的不同部分相互協調。
?
您可以鎖定整個文件或者文件的一部分。如果您獲取一個排它鎖,那么其他人就不能獲得同一個文件或者文件的一部分上的鎖。如果您獲得一個共享鎖,那么其他人可以獲得同一個文件或者文件一部分上的共享鎖,但是不能獲得排它鎖。文件鎖定并不總是出于保護數據的目的。例如,您可能臨時鎖定一個文件以保證特定的寫操作成為原子的,而不會有其他程序的干擾。
?
大多數操作系統提供了文件系統鎖,但是它們并不都是采用同樣的方式。有些實現提供了共享鎖,而另一些僅提供了排它鎖。事實上,有些實現使得文件的鎖定部分不可訪問,盡管大多數實現不是這樣的。
?
在本節中,您將學習如何在?NIO?中執行簡單的文件鎖過程,我們還將探討一些保證被鎖定的文件盡可能可移植的方法。
?
1.2文件鎖定和可移植性
?
文件鎖定可能是一個復雜的操作,特別是考慮到不同的操作系統是以不同的方式實現鎖這一事實。下面的指導原則將幫助您盡可能保持代碼的可移植性:
只使用排它鎖。
將所有的鎖視為勸告式的(advisory)。
public class UseFileLocks {static private final int start = 10;static private final int end = 20;static public void main( String args[] ) throws Exception {new Thread(new Runnable() {public void run() {// Get file channelRandomAccessFile raf = null;try {raf = new RandomAccessFile( "usefilelocks.txt", "rw" );} catch (FileNotFoundException e) {// TODO Auto-generated catch block e.printStackTrace();}FileChannel fc = raf.getChannel();// Get lockSystem.out.println( "trying to get lock" );FileLock lock = null;try {lock = fc.lock( start, end, false );} catch (IOException e) {// TODO Auto-generated catch block e.printStackTrace();}System.out.println( "got lock!" );// PauseSystem.out.println( "pausing" );try { Thread.sleep( 5000 ); } catch( InterruptedException ie ) {}// Release lockSystem.out.println( "going to release lock" );try {lock.release();} catch (IOException e) {// TODO Auto-generated catch block e.printStackTrace();}System.out.println( "released lock" );try {raf.close();} catch (IOException e) {// TODO Auto-generated catch block e.printStackTrace();}}}).start();new Thread(new Runnable() {public void run() {// Get file channelRandomAccessFile raf = null;try {raf = new RandomAccessFile( "usefilelocks.txt", "rw" );} catch (FileNotFoundException e) {// TODO Auto-generated catch block e.printStackTrace();}FileChannel fc = raf.getChannel();// Get lockSystem.out.println( "trying to get lock" );FileLock lock = null;try {lock = fc.lock( start, end, false );} catch (IOException e) {// TODO Auto-generated catch block e.printStackTrace();}System.out.println( "got lock!" );// Release lockSystem.out.println( "going to release lock" );try {lock.release();} catch (IOException e) {// TODO Auto-generated catch block e.printStackTrace();}System.out.println( "released lock" );try {raf.close();} catch (IOException e) {// TODO Auto-generated catch block e.printStackTrace();}}}).start();}}
運行結果:
trying to get lock
trying to get lock
got lock!
going to release lock
released lock
Exception in thread "Thread-0" java.nio.channels.OverlappingFileLockException
at sun.nio.ch.SharedFileLockTable.checkList(Unknown Source)
at sun.nio.ch.SharedFileLockTable.add(Unknown Source)
at sun.nio.ch.FileChannelImpl.lock(Unknown Source)
at zhongqiu.common.base.nio.UseFileLocks$1.run(UseFileLocks.java:28)
at java.lang.Thread.run(Unknown Source)