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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java 进程间文件锁FileLock详解

發(fā)布時(shí)間:2023/12/3 java 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 进程间文件锁FileLock详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載自??Java 進(jìn)程間文件鎖FileLock詳解

?最近需要在兩個(gè)進(jìn)程中對(duì)同一個(gè)文件進(jìn)行操作,正好Java 提供了文件鎖FileLock類,利用這個(gè)類可以控制不同程序(JVM)對(duì)同一文件的并發(fā)訪問(wèn),實(shí)現(xiàn)進(jìn)程間文件同步操作。

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

?“Locks are associated with files, not channels. Use locks to coordinate?with external processes, not between threads in the same JVM.”

1. 概念

  • 共享鎖: 共享讀操作,但只能一個(gè)寫(讀可以同時(shí),但寫不能)。共享鎖防止其他正在運(yùn)行的程序獲得重復(fù)的獨(dú)占鎖,但是允許他們獲得重復(fù)的共享鎖。
  • 獨(dú)占鎖: 只有一個(gè)讀或一個(gè)寫(讀和寫都不能同時(shí))。獨(dú)占鎖防止其他程序獲得任何類型的鎖。

2. FileLock FileChannel.lock(long position, long size, boolean shared)

  • shared的含義:是否使用共享鎖,一些不支持共享鎖的操作系統(tǒng),將自動(dòng)將共享鎖改成排它鎖。可以通過(guò)調(diào)用isShared()方法來(lái)檢測(cè)獲得的是什么類型的鎖。

3. lock()和tryLock()的區(qū)別:

  • lock()阻塞的方法,鎖定范圍可以隨著文件的增大而增加。無(wú)參lock()默認(rèn)為獨(dú)占鎖;有參lock(0L, Long.MAX_VALUE, true)為共享鎖。
  • tryLock()非阻塞,當(dāng)未獲得鎖時(shí),返回null.

4. FileLock的生命周期:在調(diào)用FileLock.release(),或者Channel.close(),或者JVM關(guān)閉

5. FileLock是線程安全的

6. 注意事項(xiàng):

  • 同一進(jìn)程內(nèi),在文件鎖沒(méi)有被釋放之前,不可以再次獲取。即在release()方法調(diào)用前,只能lock()或者tryLock()一次。
  • 文件鎖的效果是與操作系統(tǒng)相關(guān)的。一些系統(tǒng)中文件鎖是強(qiáng)制性的,就當(dāng)Java的某進(jìn)程獲得文件鎖后,操作系統(tǒng)將保證其它進(jìn)程無(wú)法對(duì)文件做操作了。而另一些操作系統(tǒng)的文件鎖是詢問(wèn)式的(advisory),意思是說(shuō)要想擁有進(jìn)程互斥的效果,其它的進(jìn)程也必須也按照API所規(guī)定的那樣來(lái)申請(qǐng)或者檢測(cè)文件鎖,不然將起不到進(jìn)程互斥的功能。所以文檔里建議將所有系統(tǒng)都當(dāng)做是詢問(wèn)式系統(tǒng)來(lái)處理,這樣程序更加安全也更容易移植。
  • 如何避免死鎖:在讀寫關(guān)鍵數(shù)據(jù)時(shí)加鎖,操作完成后解鎖;一次性申請(qǐng)所有需要的資源,并且在申請(qǐng)不成功的情況下放棄已申請(qǐng)到的資源。

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. 對(duì)于一個(gè)只讀文件通過(guò)任意方式加鎖時(shí)會(huì)報(bào)NonWritableChannelException異常 //2. 無(wú)參lock()默認(rèn)為獨(dú)占鎖,不會(huì)報(bào)NonReadableChannelException異常,因?yàn)楠?dú)占就是為了寫 //3. 有參lock()為共享鎖,所謂的共享也只能讀共享,寫是獨(dú)占的,共享鎖控制的代碼只能是讀操作,當(dāng)有寫沖突時(shí)會(huì)報(bào)NonWritableChannelException異常 channel = new FileOutputStream("logfile.txt",true).getChannel(); RandomAccessFile raf = new RandomAccessFile("logfile.txt","rw"); //在文件末尾追加內(nèi)容的處理 raf.seek(raf.length()); channel = raf.getChannel(); //獲得鎖方法一:lock(),阻塞的方法,當(dāng)文件鎖不可用時(shí),當(dāng)前進(jìn)程會(huì)被掛起 lock = channel.lock();//無(wú)參lock()為獨(dú)占鎖 //lock = channel.lock(0L, Long.MAX_VALUE, true);//有參lock()為共享鎖,有寫操作會(huì)報(bào)異常 //獲得鎖方法二:trylock(),非阻塞的方法,當(dāng)文件鎖不可用時(shí),tryLock()會(huì)得到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(); } } } } }

總結(jié)

以上是生活随笔為你收集整理的Java 进程间文件锁FileLock详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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