开发者社区> 问答> 正文

关于 Java 文件锁的一些问题

在线程级上:如果一个线程在某个文件上获得了一个独占锁,然后第二个线程利用一个单独打开的通道来请求该文件的独占锁,那么第二个线程的请求会被批准。
试了一下,总结了在进程级上运行的几点:

<1>当使用独占锁的时候,除了该进程其他的进程都不能访问被锁定的文件,其他进程会阻塞在 lock() 代码处;
<2>当使用独占锁的时候,该进程可以对文件进行写操作,因为这是其他试图获取锁的会被阻塞;此时执行写操作是线程安全的;

<3>当使用共享锁的时候,所有其他进程都可以获取锁,并且可以并行的进行读操作;
<4>当使用共享锁的时候,调用 write 方法修改会抛出异常,因为所有的进程都可以获取读文件锁,执行写操作是线程不安全的。

 public class FileLockTest {
        public static void main(String[] args) throws IOException {
            RandomAccessFile raf1 = new RandomAccessFile("test.dat", "rw");
            //RandomAccessFile raf2 = new RandomAccessFile("test.dat", "rw");
            FileChannel channel1 = raf1.getChannel();
            //FileChannel channel2 = raf2.getChannel();
            new Task(channel1).start();
            //new Task(channel2).start();
        }
    }    
    
    class Task extends Thread{
        FileChannel channel;
        public Task(FileChannel channel){
            this.channel = channel;
        }
        @Override
        public void run(){
            FileLock fileLock = null;
            try{
                System.out.println("Try lock file!");
                //fileLock = channel.lock(0, channel.size(), false);
                fileLock = channel.lock(0, channel.size(), true);
                ByteBuffer buffer = ByteBuffer.allocate(10);
                channel.read(buffer);
                System.out.println(Arrays.toString(buffer.array()));
                System.out.println("Locked!");
                while(true){
                    //保持持有文件锁
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch(Exception ex){
                ex.printStackTrace();
            }finally{
                if(fileLock!=null){
                    try {
                        fileLock.release();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

通过修改代码可并多次执行改程序以验证这几点,但是关于进程级的文件锁却有一点问题,因为不管如何,我在取消掉main() 方法的注释之后执行多个线程获取锁的操作都会抛出
java.nio.channels.OverlappingFileLockException
这是为什么呢?

展开
收起
蛮大人123 2016-03-06 15:52:35 2360 0
1 条回答
写回答
取消 提交回答
  • 我说我不帅他们就打我,还说我虚伪

    首先,你设置的锁并不是共享的,也就是说你的其他线程再次申请锁的时候就是会失败的。
    另外,你使用的是NIO的形式,本身就是避免阻塞发生的,所有这里将本来将要发生的阻塞转换成了异常抛出,这样你就能继续执行程序。

    2019-07-17 18:54:47
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
OpenCrypto Unchaining the Java 立即下载
Java Your(Next) 立即下载
Java8简明教程 立即下载