js css html

多进程同步之文件锁

2023-02-26  本文已影响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;

方法:

参数:

使用示例

进程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启动:

总结

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

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

猜你喜欢

热点阅读