多進(jìn)程同步之文件鎖

在多線程的環(huán)境下,如果兩個線程操作相同的競爭區(qū),需要使用鎖來保證線程安全。在Java中有多種選擇,如Synchronized關(guān)鍵字,CountDownLatch等等。但是這些方式,在多進(jìn)程的情況下,會失效。

那么在多進(jìn)程情況下,我們怎么做進(jìn)程同步呢?答案是文件鎖。Java提供的FileLock類,可以實現(xiàn),下面來看看具體的用法。

FileLock API

    public abstract FileLock lock(long position, long size, boolean shared) throws IOException;

    public final FileLock lock() throws IOException;

    public abstract FileLock tryLock(long position, long size, boolean shared) throws IOException;
    
    public final FileLock tryLock() throws IOException;

方法:

  • lock方法,會block住線程,直到獲取到鎖。
  • tryLock方法,不會block,會直接返回,如果能獲取到鎖,則返回FileLock對象,如果獲取不到鎖,返回null。

參數(shù):

  • position:鎖定文件中的開始位置
  • size:鎖定文件中的內(nèi)容長度
  • shared:是否使用共享鎖。true為共享鎖;false為獨占鎖。
    • 共享鎖:允許其他進(jìn)程同時獲取
    • 獨占鎖:不允許其他進(jìn)程同時獲取

使用示例

進(jìn)程1

    public static void main(String[] args) {
        try {
            // 打開文件
            FileOutputStream raf = new FileOutputStream("lock.txt");
            // 獲取FileChannel
            FileChannel channel = raf.getChannel();
            // 獲取FileLock,上鎖
            FileLock lock = channel.lock();
            Thread.sleep(10000);
            // 手動釋放FileLock
            lock.close();
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }

進(jìn)程1啟動后,會獲取FileLock鎖,然后持有鎖Sleep 10s。

進(jìn)程2:

    public static void main(String[] args) {
        try {
            FileOutputStream raf = new FileOutputStream("lock.txt");
            FileChannel channel = raf.getChannel();
            // 會被block,直到獲得鎖
            FileLock lock = channel.lock();
            // 如果沒有獲得鎖,直接返回null,不會被block  
            lock = channel.tryLock();
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }

此時進(jìn)程2啟動:

  • 如果調(diào)用lock方法,會block線程,直到進(jìn)程1釋放鎖。
  • 如果調(diào)用tryLock方法,不會block,會直接返回,如果能獲取到鎖,則返回FileLock對象,如果獲取不到鎖,返回null

總結(jié)

FileLock可以用于Android中多進(jìn)程同步,有以下幾點需要注意:

  1. 如果同一個進(jìn)程中的不同線程,同時對一個文件進(jìn)行加鎖操作,會直接拋出異常:java.nio.channels.OverlappingFileLockException
  2. FileLock釋放的條件是,手動調(diào)用release/close釋放,或JVM終止運行。
  3. 本質(zhì)也是調(diào)用Linuxfnctl來從內(nèi)核對文件進(jìn)行加鎖。
  4. 同一個FileChannel只能被使用一次,如果調(diào)用close之后,再去調(diào)用lock,會報ClosedChannelExcption。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容