FileLock——Java文件锁

使用FileLock可以给文件加锁,在多线程和多进程的情况下均有效。(File类的setReadable()等方法只在当前线程中有效。)

代码场景为写进程先获取锁,向文件中写入一串数字后释放锁。读进程等待写进程释放锁后获取锁并输出文件大小。

写进程代码:

import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

public class WriteProcess {

    public static void main(String[] arg) throws Exception {
        RandomAccessFile randomAccessFile = null;
        FileChannel channel = null;

        try {
            randomAccessFile = new RandomAccessFile("test.txt", "rw");
            channel = randomAccessFile.getChannel();
            FileLock lock = null;

            while (null == lock) {
                try {
                    lock = channel.lock();
                } catch (Exception e) {
                    System.out.println("Write Process : get lock failed");
                }
            }

            System.out.println("Write Process : get lock");

            for (int i = 0; i < 30; i++) {
                randomAccessFile.writeByte(i);
                System.out.println("Write Process : write " + i);

                Thread.sleep(1000);
            }

            lock.release();
            System.out.println("Write Process : release lock");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != randomAccessFile) {
                randomAccessFile.close();
            }
            if (null != channel) {
                channel.close();
            }
        }
    }
}

读进程代码:

import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

public class ReadProcess {

    public static void main(String[] arg) throws Exception {
        RandomAccessFile randomAccessFile = null;
        FileChannel channel = null;

        try {
            Thread.sleep(10000);

            randomAccessFile = new RandomAccessFile("test.txt", "rw");
            channel = randomAccessFile.getChannel();
            FileLock lock = null;

            while (true) {
                lock = channel.tryLock();

                if (null == lock) {
                    System.out.println("Read Process : get lock failed");
                    Thread.sleep(1000);
                } else {
                    break;
                }
            }

            System.out.println("Read Process : get lock");

            System.out.println("Read Process : get " + randomAccessFile.length() + " numbers");

            lock.release();
            System.out.println("Read Process : release lock");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != randomAccessFile) {
                randomAccessFile.close();
            }
            if (null != channel) {
                channel.close();
            }
        }
    }
}

同时运行读写进程,写进程输出如下:

Write Process : get lock Write Process : write 0 Write Process : write 1 Write Process : write 2 Write Process : write 3 …… Write Process : write 28 Write Process : write 29 Write Process : release lock

读进程输出如下:

……
Read Process : get lock failed Read Process : get lock failed Read Process : get lock failed Read Process : get lock failed Read Process : get lock failed Read Process : get lock Read Process : get 30 numbers Read Process : release lock

这里需要注意:

  • 如果同为写进程,可以都使用OutoutStream;
  • 如果为一读一写,使用InputStream和OutoutStream无法达到加锁的效果。改为使用RandomAccessFile后,读写进程还必须使用相同的模式(此例中为rw)才可以成功加锁。
  • 另外,lock()方法和tryLock()的区别就是lock()是阻塞的,tryLock()是非阻塞的。
    原文作者:java锁
    原文地址: https://blog.csdn.net/u010908723/article/details/79189221
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞