JAVA文件锁

[size=medium] 最近项目里碰到了个问题,在Linux环境上,Thread1通过java.nio.channels.FileLock给文件加锁,通过Thread2竟然能删除这个文件,突然感觉很奇怪,Windows环境上不是这样的行为啊,因此就顺便研究了下java文件锁的机制。
首先看一下如何简单实现一个java的文件锁[/size]


package com.pracbiz.b2bportal.core.eai.backend;

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

public class TestLock
{
public static void main(String[] args) throws IOException, InterruptedException
{
RandomAccessFile input = null;
FileChannel channel = null;
FileLock lock = null;
final File source = new File("/Users/youwenwu/Downloads/a.txt");
try
{
if (source.exists())
{
input = new RandomAccessFile(source, "rw");
//step 1.获取FileChannel,获取channel有3种方式,分别是调用
//FileInputStream,FileOutputStream以及RandomAccessFile
//实例的getChannel方法.
channel = input.getChannel();
//step 2.获取FileLock
lock = channel.tryLock();
}
}
finally
{
if (lock != null)
{
lock.release();
lock = null;
}

if (channel != null)
{
channel.close();
channel = null;
}

if (input != null)
{
input.close();
input = null;
}
}
}
}


[size=medium] FileLock是通过调用FileChannel的lock或tryLock方法来获取的,lock获取不到当前线程会处于阻塞等待状态,tryLock不管是否成功获得锁都会立即返回。
FileLock分两种,共享锁(shared)和排它锁(exclusive),多个线程可以同时持有同一个文件的共享锁,但但如果有一个线程持有了一个文件的排它锁,则其它线程将无法获取该文件的锁(包括共享锁和排它锁),这里有一点要特别留意,并不是所有的操作系统都支持共享锁,如果某个操作系统不支持共享锁,那么FileChannel的lock或tryLock会自动返回排它锁,如何判断一个FileLock为共享锁还是排它锁,只需要调用lock.isShared方法即可,返回true则为共享锁,false为排它锁。
那接下来回到我们之前的问题,为什么Linux环境下,Thread1持有File1的lock,但是Thread2却能删除File1,我们知道,对于结构型数据库,如果一个存储过程对某一张表中的某一条记录加锁,那另一个存储过程是无法删除该条记录的,这是因为删除一条记录需要获取该记录的独占锁,但是一条记录的独占锁同一时刻只能由一个存储过程获取,所以很显然,这里是删除失败(关于数据库的锁目前就点到为止,不是我们这篇文章需要讨论的范围),那么这里很容易让我们想到,难道Thread2在删除File1的时候不需要获取该文件的锁?这样不是非常不安全吗?带着这个疑问,我查了java api发现,原来锁在操作系统级别有两个特征,协同(advisory)和强制(mandatory),这个是平台相关的,windows平台的锁是mandatory的,linux平台的锁则是advisory的,关于这两种特征的行为,大致可以总结为以下两点,advisory特征的锁并不会阻止其它线程对该文件的访问甚至删除,但mandatory特征的锁会完全阻止其它线程对文件的任何违反锁规则的访问(比如read并不会违反锁规则,但update或者delete却是违反了锁规则),而且java api也明确的告诉我们不要希望lock来帮你阻止其它程序对文件的访问。
该贴持续更新,会加入更多实验数据
[/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值