日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

聊一聊Java中的文件锁

發(fā)布時間:2024/4/11 java 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 聊一聊Java中的文件锁 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

點擊上方“朱小廝的博客”,選擇“設為星標”

后臺回復”加群“獲取公眾號專屬群聊入口

1. 概覽

當讀寫文件時,需要確保有適當?shù)奈募i定機制,來保證基于并發(fā)I/O應用程序的數(shù)據(jù)完整性。

「本教程中, 我們將介紹使用 Java NIO 庫實現(xiàn)這一點的各種方法。」

2. 文件鎖簡介

「一般來說,有兩種鎖」:

  • 獨占鎖——也稱為寫鎖

  • 共享鎖——也稱為讀鎖

簡單地說,在寫操作完成時,獨占鎖防止所有其他操作(包括讀操作)。

相反,共享鎖允許多個進程同時讀取。讀鎖的目的是防止另一個進程獲取寫鎖。通常,處于一致狀態(tài)的文件確實應該被任何進程讀取。

在下一節(jié)中,我們將看到Java如何處理這些類型的鎖。

3. Java中的文件鎖

Java NIO庫支持在操作系統(tǒng)級別鎖定文件。FileChannel?中的lock()?和*tryLock()*方法就是為了這個而存在。

我們可以通過?FileInputStream,?FileOutputStream,RandomAccessFile?來獲取FileChannel,三者均可通過?getChannel()?方法返回?FileChannel對象.

或者, 我們可以直接通過靜態(tài)方法?open?來創(chuàng)建?FileChannel??:

try (FileChannel channel = FileChannel.open(path, openOptions)) {// write to the channel }

接下來,我們將回顧在Java中獲取獨占鎖和共享鎖的不同方式。要了解有關文件通道的更多信息,請查看[Guide to Java FileChanne 教程。

4. 獨占鎖

正如我們已經(jīng)了解到的,在寫入文件時,「我們可以使用獨占鎖」防止其他進程讀取或寫入文件。

我們通過調用?FileChannel?類上的?lock()?或?tryLock())?來獲得獨占鎖。我們還可以使用它們的重載方法:

  • lock(long position, long size, boolean shared)

  • tryLock(long position, long size, boolean shared)

在這些情況下,shared參數(shù)必須設置為false。

要獲得獨占鎖,必須使用可寫的文件通道。我們可以通過?FileOutputStream?或?RandomAccessFile?的?getChannel()?方法創(chuàng)建它。或者,如前所述,我們可以使用?FileChannel?類的靜態(tài)方法:open。我們只需要將第二個參數(shù)設置為StandardOpenOption.APPEND?:

try (FileChannel channel = FileChannel.open(path, StandardOpenOption.APPEND)) { // write to channel }

4.1. 使用?FileOutputStream?的獨占鎖

從?FileOutputStream?創(chuàng)建的?FileChannel?是可寫的。因此,我們可以獲得一個獨占鎖:

try (FileOutputStream fileOutputStream = new FileOutputStream("/tmp/testfile.txt");FileChannel channel = fileOutputStream.getChannel();FileLock lock = channel.lock()) { // write to the channel }

在這里,channel.lock()?要么阻塞直到獲得一個鎖,要么拋出一個異常。例如,如果指定的區(qū)域已鎖定,則會引發(fā)OverlappingFileLockException。有關可能的異常的完整列表,請參見Javadoc。我們還可以使用?channel.tryLock()?執(zhí)行非阻塞鎖。如果由于另一個程序持有一個重疊的鎖而無法獲取鎖,則返回null。如果由于任何其他原因未能執(zhí)行此操作,則會引發(fā)相應的異常。

4.2. 使用?RandomAccessFile?的獨占鎖

使用?RandomAccessFile,我們需要設置 [constructor](https://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html#RandomAccessFile(java.io.File, java.lang.String)) 方法的第二個參數(shù)。

在這里,我們將使用讀寫權限打開文件:

try (RandomAccessFile file = new RandomAccessFile("/tmp/testfile.txt", "rw");FileChannel channel = file.getChannel();FileLock lock = channel.lock()) {// write to the channel }

如果我們以只讀模式打開文件,并嘗試向其通道進行寫入操作,將會拋出?NonWritableChannelException?異常。

4.3.獨占鎖依賴于可讀的?FileChannel

如前所述,獨占鎖需要一個可寫通道。因此,我們無法通過從?FileInputStream?創(chuàng)建的?FileChannel?獲得獨占鎖:

Path path = Files.createTempFile("foo","txt"); Logger log = LoggerFactory.getLogger(this.getClass()); try (FileInputStream fis = new FileInputStream(path.toFile()); FileLock lock = fis.getChannel().lock()) {// unreachable code } catch (NonWritableChannelException e) {// handle exception }

在上面的例子中,lock()?方法將拋出一個?nonwriteablechannelexception?。實際上,這是因為我們正在對一個創(chuàng)建只讀通道的?FileInputStream?調用?getChannel。這個例子只是為了證明我們不能寫到一個不可寫的通道。事實上,我們不會捕捉并重新拋出異常。

5. ?共享鎖

記住,共享鎖也稱為讀?鎖。因此,要獲得讀鎖,我們必須使用可讀的文件通道。

這樣的?FileChannel?可以通過調用?FileInputStream?或?RandomAccessFile?上的?getChannel()?方法獲得。同樣,另一個選項是使用?FileChannel?類的靜態(tài)?open?方法。在這種情況下,我們將第二個參數(shù)設置為?StandardOpenOption.READ?。

try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ);FileLock lock = channel.lock(0, Long.MAX_VALUE, true)) {// read from the channel }

這里要注意的一點是,我們選擇通過調用?lock(0, Long.MAX_VALUE, true)?來鎖定整個文件。通過將前兩個參數(shù)更改為不同的值,我們還可以只鎖定文件的特定區(qū)域。對于共享鎖,第三個參數(shù)必須設置為true。

為了簡單起見,我們將在下面的所有示例中鎖定整個文件,但請記住,我們始終可以鎖定文件的特定區(qū)域。

5.1. 使用?FileInputStream?中的共享鎖

從?FileInputStream?獲得的?FileChannel?是可讀的。因此,我們可以獲得一個共享鎖:

try (FileInputStream fileInputStream = new FileInputStream("/tmp/testfile.txt");FileChannel channel = fileInputStream.getChannel();FileLock lock = channel.lock(0, Long.MAX_VALUE, true)) {// read from the channel }

在上面的代碼片段中,將成功調用通道上的?lock()?。這是因為共享鎖只要求通道是可讀的就行。

5.2. 使用?RandomAccessFile中的共享鎖

這次,我們只需要使用 ''讀" 權限打開文件即可:

try (RandomAccessFile file = new RandomAccessFile("/tmp/testfile.txt", "r"); FileChannel channel = file.getChannel();FileLock lock = channel.lock(0, Long.MAX_VALUE, true)) {// read from the channel }

在本例中,我們創(chuàng)建了一個具有讀取權限的RandomAccessFile對象,然后從中創(chuàng)建一個可讀通道,從而創(chuàng)建一個共享鎖。

5.3. 共享鎖依賴于可讀的?FileChannel

因此,我們無法通過從?FileOutputStream?創(chuàng)建的?FileChannel?獲取共享鎖:

Path path = Files.createTempFile("foo","txt"); try (FileOutputStream fis = new FileOutputStream(path.toFile()); FileLock lock = fis.getChannel().lock(0, Long.MAX_VALUE, true)) {// unreachable code } catch (NonWritableChannelException e) { // handle exception }

在本例中,調用?lock()?嘗試獲取從?FileOutputStream?創(chuàng)建的通道上的共享鎖。這樣的通道是只寫的。它不能滿足通道必須可讀的需要。這將觸發(fā)一個NonWritableChannelException。

同樣,這段代碼只是為了證明我們不能從一個不可讀的通道中讀取。

6. 思考

實際上,使用文件鎖是困難的;鎖定機制是不可移植的。我們需要考慮到這一點來設計鎖定邏輯。

在POSIX系統(tǒng)中,鎖是建議性的。讀取或寫入給定文件的不同進程必須就鎖定協(xié)議達成一致。這將確保文件的完整性。操作系統(tǒng)本身不會強制任何鎖定。

在Windows上,除非允許共享,否則鎖將是獨占的。討論操作系統(tǒng)特定機制的優(yōu)點或缺點超出了本文的討論范圍。然而,在實現(xiàn)鎖定機制時,了解這些細微差別很重要。

7. 總結

在本教程中,我們回顧了在Java中獲取文件鎖的幾種不同選項。

首先,我們首先了解兩種主要的鎖定機制,以及Java NIO庫如何促進鎖定文件。然后,我們?yōu)g覽了一系列簡單的示例,這些示例顯示我們可以在應用程序中獲得獨占和共享鎖。我們還研究了使用文件鎖時可能遇到的典型異常類型。?

想知道更多?描下面的二維碼關注我

后臺回復”加群“獲取公眾號專屬群聊入口

字節(jié)跳動2020春季實習生招聘及校招全職補錄全面啟動!

【精彩推薦】

  • 咱們從頭到尾說一次Java垃圾回收

  • Netty、Kafka中的零拷貝技術到底有多牛?

  • go為什么這么快?

  • 面試前,我們要復習多少Redis知識?

  • 《深入理解Java虛擬機》第2版挖的坑終于在第3版中被R大填平了

  • Redis性能問題分析

  • 淺談CAP和Paxos共識算法

朕已閱?

總結

以上是生活随笔為你收集整理的聊一聊Java中的文件锁的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。