最近项目里碰到了个问题,在Linux环境上,Thread1通过java.nio.channels.FileLock给文件加锁,通过Thread2竟然能删除这个文件,突然感觉很奇怪,Windows环境上不是这样的行为啊,因此就顺便研究了下java文件锁的机制。
首先看一下如何简单实现一个java的文件锁
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;
}
}
}
}
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来帮你阻止其它程序对文件的访问。
该贴持续更新,会加入更多实验数据
分享到:
相关推荐
:Java新IO】_文件锁笔记032003
主要介绍了java 文件锁的简单实现的相关资料,需要的朋友可以参考下
NULL 博文链接:https://sosuny.iteye.com/blog/704587
只锁一个文件,excel word 自带密码不好用,就试一下这个吧单个文锁,目前我也没找到破解的方法,如果忘记密码的了呵呵呵,上帝保佑,如你知也通知我一下吧 ths
Java NIO 源码适合初学者,里面包括通道和Buffer的基本适用,以及文件锁,和内存文件映射等等
java 读取 XML 使用 xml 。。。。。。。。。。。
此文档能够让读者彻底了解JAVA开发中的多线程并发锁的使用
很久以前的工具类代码不过很实用,java的文件读写创建目录复制,移动,文件序列化,反序列化,文件锁,xml文件的读取,诸多内容囊括其中注释也十分详细,学习文件流的不二选择
该项目旨在实现h5与fastdfs之间的高性能断点续传、秒传、大文件上传以及使用redis文件锁。系统提供了文件上传、文件处理、文件存储等功能。通过该项目,开发者可以学习并实践Java技术的应用,为后续的Web开发奠定...
javacore.txt文件用jca打开,heapdump.phd文件用ha打开。...包括 Java 虚拟机的参数,环境变量,内存段的分配情况,垃圾回收日志,各种内部锁的状态,各线程在当前时刻的运行栈,以及类加载状态等。
文件锁、映射的I/O技术以及数据结构与集合;服务器端Java技术部分讨论了JFC/Swing CGI开发、Applet、容器布局以及图形编程等技术;企业级Java技术部分讨论了JDBC API、EJB体系结构的基础知识、Java平台安全方案以及...
该文件是使用javaweb相关的知识编写的关于用户登录界面实现滑动图片解锁实现安全登录的功能项目
java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...
CDN静态文件访问 分布式存储 分布式搜索引擎 应用发布与监控 应用容灾及机房规划 系统动态扩容 分布式架构策略-分而治之 从简到难,从网络通信探究分布式通信原理 基于消息方式的系统间通信 理解通信协议...
java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...
适合已经学过锁这方面知识的小伙伴进行学习,思维导图对各种锁进行了详细整理总结,采用思维导图的方式更加方便大伙们学习并记忆。
由于Java Web开发技术大全pdf文件太大120多M,上传资源要求在20M以内,所以大家必须要把Java Web开发技术大全.z01,Java Web开发技术大全.z02,Java Web开发技术大全.z03,Java Web开发技术大全.z04,Java Web开发...
直接给文件夹的内容加上一个密码锁,可以防止外人访问内容。
实现一个拷贝文件的类使用字节流还是字符串.mp4 │ Java面试题13.线程的实现方式 怎么启动线程怎么区分线程.mp4 │ Java面试题14.线程并发库和线程池的作用?.mp4 │ Java面试题15.设计模式和常用的设计模式.mp4 │ ...