JAVA 文件鎖 FileLock

概述

FileLock是java 1.4 版本后出現(xiàn)的一個(gè)類,它可以通過對一個(gè)可寫文件(w)加鎖赫模,保證同時(shí)只有一個(gè)進(jìn)程可以拿到文件的鎖树肃,這個(gè)進(jìn)程從而可以對文件做訪問;而其它拿不到鎖的進(jìn)程要么選擇被掛起等待瀑罗,要么選擇去做一些其它的事情胸嘴, 這樣的機(jī)制保證了眾進(jìn)程可以順序訪問該文件雏掠。也可以看出,能夠利用文件鎖的這種性質(zhì)劣像,在一些場景下乡话,雖然我們不需要操作某個(gè)文件, 但也可以通過 FileLock 來進(jìn)行并發(fā)控制驾讲,保證進(jìn)程的順序執(zhí)行蚊伞,避免數(shù)據(jù)錯(cuò)誤席赂。

共享鎖吮铭、獨(dú)占鎖

  • 共享鎖:允許多個(gè)線程進(jìn)行文件的讀取操作
  • 獨(dú)占鎖: 只允許一個(gè)線程進(jìn)行文件的讀/寫操作

獲得 FileLock

通過 NIO 的 API 首先獲取文件的 FileChannel ,然后可以通過 FileChannel 以下4中方式獲取FileLock颅停。

1. 通過lock() 獲取 FileLock谓晌,獲取文件的獨(dú)占鎖

public final FileLock lock() throws IOException {
    return lock(0L, Long.MAX_VALUE, false);
}

默認(rèn)鎖定整個(gè)文件,并設(shè)置為獨(dú)占鎖癞揉。

2. 通過改方法可以鎖定文件的部分?jǐn)?shù)據(jù)纸肉,并支持設(shè)置共享鎖。

public FileLock lock(long position, long size, boolean shared) throws IOException{
  ......
}
  • position:鎖定文件中的開始位置
  • size: 鎖定文件中的內(nèi)容長度
  • shared: 是否使用共享鎖喊熟。true為共享鎖定柏肪;false為獨(dú)占鎖定。

一些不支持共享鎖的操作系統(tǒng),將自動(dòng)將共享鎖改成排它鎖芥牌》澄叮可以通過調(diào)用isShared()方法來檢測獲得的是什么類型的鎖。

3. 試圖獲取文件獨(dú)占鎖

public final FileLock tryLock() throws IOException {
    return tryLock(0L, Long.MAX_VALUE, false);
}

如果獲取不到鎖壁拉,則返回null谬俄。而不阻塞當(dāng)前線程,等待獲取鎖弃理。

4. 通過改方法可以嘗試獲得文件的部分?jǐn)?shù)據(jù)的鎖溃论,并支持設(shè)置共享鎖。

public abstract FileLock tryLock(long position, long size, boolean shared) throws IOException{
    ......
}

參數(shù)同上2痘昌。
如果獲取不到鎖钥勋,則返回null。

使用場景

  1. 如果多個(gè)應(yīng)用部署到同一臺機(jī)器上辆苔,并且同時(shí)操作同一份數(shù)據(jù)(數(shù)據(jù)庫中或文件中的數(shù)據(jù))算灸,可以使用FileLock充當(dāng)分布式鎖。

示例

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

public class FileLockTest {  
  
    public static void main(String[] args){  
        FileLock lock = null;  
        try (FileChannel channel = new FileOutputStream("d:\\file.lock",true).getChannel()){  
            lock = channel.lock();//無參lock()為獨(dú)占鎖
            //lock = channel.lock(0L, channel.size(), true);    //共享鎖
            //其它邏輯
            ......
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            if (lock != null) {  
                try {  
                    lock.release();  
                    lock = null;  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }  
}  
  1. 對于一個(gè)只讀文件通過任意方式加鎖時(shí)會報(bào)NonWritableChannelException異常
  2. 無參lock()默認(rèn)為獨(dú)占鎖姑子,不會報(bào)NonReadableChannelException異常乎婿,因?yàn)楠?dú)占就是為了寫
  3. 有參lock()為共享鎖,所謂的共享也只能讀共享街佑,寫是獨(dú)占的谢翎,共享鎖控制的代碼只能是讀操作捍靠,當(dāng)有寫沖突時(shí)會報(bào)NonWritableChannelException異常

想了解更多精彩內(nèi)容請關(guān)注我的公眾號

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市森逮,隨后出現(xiàn)的幾起案子榨婆,更是在濱河造成了極大的恐慌,老刑警劉巖褒侧,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件良风,死亡現(xiàn)場離奇詭異,居然都是意外死亡闷供,警方通過查閱死者的電腦和手機(jī)烟央,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歪脏,“玉大人疑俭,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵晓折,是天一觀的道長惫谤。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮飘弧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嵌溢。我一直安慰自己眯牧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布赖草。 她就那樣靜靜地躺著学少,像睡著了一般。 火紅的嫁衣襯著肌膚如雪秧骑。 梳的紋絲不亂的頭發(fā)上版确,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天,我揣著相機(jī)與錄音乎折,去河邊找鬼绒疗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛骂澄,可吹牛的內(nèi)容都是我干的吓蘑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼磨镶!你這毒婦竟也來了溃蔫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤琳猫,失蹤者是張志新(化名)和其女友劉穎伟叛,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脐嫂,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡统刮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了账千。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侥蒙。...
    茶點(diǎn)故事閱讀 39,764評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蕊爵,靈堂內(nèi)的尸體忽然破棺而出辉哥,到底是詐尸還是另有隱情桦山,我是刑警寧澤攒射,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站恒水,受9級特大地震影響会放,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜钉凌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一咧最、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧御雕,春花似錦矢沿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至闽坡,卻和暖如春栽惶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疾嗅。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工外厂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人代承。 一個(gè)月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓汁蝶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親论悴。 傳聞我的和親對象是個(gè)殘疾皇子掖棉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評論 2 354

推薦閱讀更多精彩內(nèi)容