Java 进程间文件锁FileLock详解
生活随笔
收集整理的這篇文章主要介紹了
Java 进程间文件锁FileLock详解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載自??Java 進程間文件鎖FileLock詳解
?最近需要在兩個進程中對同一個文件進行操作,正好Java 提供了文件鎖FileLock類,利用這個類可以控制不同程序(JVM)對同一文件的并發訪問,實現進程間文件同步操作。
? ? ?FileLock是java 1.4 版本后出現的一個類,它可以通過對一個可寫文件(w)加鎖,保證同時只有一個進程可以拿到文件的鎖,這個進程從而可以對文件做訪問;而其它拿不到鎖的進程要么選擇被掛起等待,要么選擇去做一些其它的事情, 這樣的機制保證了眾進程可以順序訪問該文件。也可以看出,能夠利用文件鎖的這種性質,在一些場景下,雖然我們不需要操作某個文件, 但也可以通過 FileLock 來進行并發控制,保證進程的順序執行,避免數據錯誤。
?“Locks are associated with files, not channels. Use locks to coordinate?with external processes, not between threads in the same JVM.”1. 概念
- 共享鎖: 共享讀操作,但只能一個寫(讀可以同時,但寫不能)。共享鎖防止其他正在運行的程序獲得重復的獨占鎖,但是允許他們獲得重復的共享鎖。
- 獨占鎖: 只有一個讀或一個寫(讀和寫都不能同時)。獨占鎖防止其他程序獲得任何類型的鎖。
2. FileLock FileChannel.lock(long position, long size, boolean shared)
- shared的含義:是否使用共享鎖,一些不支持共享鎖的操作系統,將自動將共享鎖改成排它鎖。可以通過調用isShared()方法來檢測獲得的是什么類型的鎖。
3. lock()和tryLock()的區別:
- lock()阻塞的方法,鎖定范圍可以隨著文件的增大而增加。無參lock()默認為獨占鎖;有參lock(0L, Long.MAX_VALUE, true)為共享鎖。
- tryLock()非阻塞,當未獲得鎖時,返回null.
4. FileLock的生命周期:在調用FileLock.release(),或者Channel.close(),或者JVM關閉
5. FileLock是線程安全的
6. 注意事項:
- 同一進程內,在文件鎖沒有被釋放之前,不可以再次獲取。即在release()方法調用前,只能lock()或者tryLock()一次。
- 文件鎖的效果是與操作系統相關的。一些系統中文件鎖是強制性的,就當Java的某進程獲得文件鎖后,操作系統將保證其它進程無法對文件做操作了。而另一些操作系統的文件鎖是詢問式的(advisory),意思是說要想擁有進程互斥的效果,其它的進程也必須也按照API所規定的那樣來申請或者檢測文件鎖,不然將起不到進程互斥的功能。所以文檔里建議將所有系統都當做是詢問式系統來處理,這樣程序更加安全也更容易移植。
- 如何避免死鎖:在讀寫關鍵數據時加鎖,操作完成后解鎖;一次性申請所有需要的資源,并且在申請不成功的情況下放棄已申請到的資源。
7. 示例代碼:
import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import java.util.Date; public class FileLockTest { public static void main(String[] args){ FileChannel channel = null; FileLock lock = null; try { //1. 對于一個只讀文件通過任意方式加鎖時會報NonWritableChannelException異常 //2. 無參lock()默認為獨占鎖,不會報NonReadableChannelException異常,因為獨占就是為了寫 //3. 有參lock()為共享鎖,所謂的共享也只能讀共享,寫是獨占的,共享鎖控制的代碼只能是讀操作,當有寫沖突時會報NonWritableChannelException異常 channel = new FileOutputStream("logfile.txt",true).getChannel(); RandomAccessFile raf = new RandomAccessFile("logfile.txt","rw"); //在文件末尾追加內容的處理 raf.seek(raf.length()); channel = raf.getChannel(); //獲得鎖方法一:lock(),阻塞的方法,當文件鎖不可用時,當前進程會被掛起 lock = channel.lock();//無參lock()為獨占鎖 //lock = channel.lock(0L, Long.MAX_VALUE, true);//有參lock()為共享鎖,有寫操作會報異常 //獲得鎖方法二:trylock(),非阻塞的方法,當文件鎖不可用時,tryLock()會得到null值 //do { // lock = channel.tryLock(); //} while (null == lock); //互斥操作 ByteBuffer sendBuffer=ByteBuffer.wrap((new Date()+" 寫入\n").getBytes()); channel.write(sendBuffer); Thread.sleep(5000); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } finally { if (lock != null) { try { lock.release(); lock = null; } catch (IOException e) { e.printStackTrace(); } } if (channel != null) { try { channel.close(); channel = null; } catch (IOException e) { e.printStackTrace(); } } } } }總結
以上是生活随笔為你收集整理的Java 进程间文件锁FileLock详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 陶琳:很多车主事故后仍选择特斯拉!这是在
- 下一篇: P 社坦言《都市:天际线 2》游戏优化未