美文网首页js css html
多进程同步之文件锁

多进程同步之文件锁

作者: 尹学姐 | 来源:发表于2023-02-26 23:07 被阅读0次

    在多线程的环境下,如果两个线程操作相同的竞争区,需要使用锁来保证线程安全。在Java中有多种选择,如Synchronized关键字,CountDownLatch等等。但是这些方式,在多进程的情况下,会失效。

    那么在多进程情况下,我们怎么做进程同步呢?答案是文件锁。Java提供的FileLock类,可以实现,下面来看看具体的用法。

    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

    参数:

    • position:锁定文件中的开始位置
    • size:锁定文件中的内容长度
    • shared:是否使用共享锁。true为共享锁;false为独占锁。
      • 共享锁:允许其他进程同时获取
      • 独占锁:不允许其他进程同时获取

    使用示例

    进程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();
            } 
        }
    

    进程1启动后,会获取FileLock锁,然后持有锁Sleep 10s。

    进程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();
            } 
        }
    

    此时进程2启动:

    • 如果调用lock方法,会block线程,直到进程1释放锁。
    • 如果调用tryLock方法,不会block,会直接返回,如果能获取到锁,则返回FileLock对象,如果获取不到锁,返回null

    总结

    FileLock可以用于Android中多进程同步,有以下几点需要注意:

    1. 如果同一个进程中的不同线程,同时对一个文件进行加锁操作,会直接抛出异常:java.nio.channels.OverlappingFileLockException
    2. FileLock释放的条件是,手动调用release/close释放,或JVM终止运行。
    3. 本质也是调用Linuxfnctl来从内核对文件进行加锁。
    4. 同一个FileChannel只能被使用一次,如果调用close只有,再去调用lock,会报ClosedChannelExcption

    相关文章

      网友评论

        本文标题:多进程同步之文件锁

        本文链接:https://www.haomeiwen.com/subject/xymcldtx.html