Java进程互斥–FileLock
原文:http://www.cnblogs.com/XL-Liang/articles/2852998.html系统中不同Java进程通常情况下运行于不同的Java虚拟机资源中(JVM),拥有独立的数据和逻辑空间,彼此秋毫无犯,并不会产生相互干扰。但 一些特殊的情况下,两个Java的进程间会对同时访问系统中相同的数据、或者同时操作相同的资源,容易产生并发错误。更多的关于进程和并
http://www.cnblogs.com/XL-Liang/articles/2852998.html
系统中不同Java进程通常情况下运行于不同的Java虚拟机资源中(JVM),拥有独立的数据和逻辑空间,彼此秋毫无犯,并不会产生相互干扰。但 一些特殊的情况下,两个Java的进程间会对同时访问系统中相同的数据、或者同时操作相同的资源,容易产生并发错误。更多的关于进程和并发的内容,请参考这里。
机会主义者总是觉得这个概率太小了,自己运气好,在自己退休之前这个潜在的bug不会爆发。不过相信我,巧合和意外总是会更轻易的发生的,尤其是业务大副增长的前提下。所以为了避免不必要的损失和批评甚至扣薪,我们要对访问同一资源的不同Java程序做并发控制。
FileLock是java 1.4 版本后出现的一个类,它可以通过对一个可写文件(w)加锁,保证同时只有一个进程可以拿到文件的锁,这个进程从而可以对文件做访问;而其它拿不到锁的进程 要么选择被挂起等待,要么选择去做一些其它的事情,这样的机制保证了众进程可以顺序访问该文件。也可以看出,能够利用文件锁的这种性质,在一些场景下,虽 然我们不需要操作某个文件,但也可以通过 FileLock 来进行并发控制,保证进程的顺序执行,避免数据错误。
package com.ngloom.lock;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Date;
public class Lock1 {
public static void main(String[] args){
//文件锁所在文件
File lockFile = new File("tmp");
FileOutputStream outStream = null;
FileLock lock = null;
try {
outStream = new FileOutputStream(lockFile);
FileChannel channel = outStream.getChannel();
try {
//方法一
lock = channel.lock();
System.out.println("Get the Lock!");
//do something...
//方法二
//lock = channel.tryLock();
//if(lock != null){
// do something..
//}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
finally{
if(null != lock){
try {
System.out.println("Release The Lock" + new Date().toString());
lock.release();
} catch (IOException e) {
e.printStackTrace();
}
}
if(outStream != null){
try {
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
如代码所示,需要进行互斥的进程只要将自己的代码替换掉//do something处即可,每个进程在运行实际逻辑功能代码之前,会尝试获取锁文件锁,得到文件锁的进程可以继续执行后续的代码,而没有获得锁文件的进程 将被操作系统挂起(suspend),等到其它进程将文件锁释放后再重新开始尝试获取文件锁。
这样子,进程就可以通过FileLock来实现间的互斥运行。
最后,关于Java的FileLock还需要再补充几点,详细的地文档请看这里:
0.可以通过lock方法来获取文件锁,可以通过tryLock方来测试该文件锁是否可用。二者的区别是那:lock()方法是阻塞的方法,当文件锁不可用时,当前进程会被挂起;tryLock是非阻塞的方法,当文件锁不可用时,tryLock()会得到null值。
1.同一进程内,在文件锁没有被释放之前,不可以再次获取。即在release()方法调用前,只能lock()或者tryLock()一次。
2. 进程锁对于同一进程来说是共享(shared)的,即这个进程中的线程都可以操作这个文件锁(且线程安全);对于不同的进程来说是互斥(exclusive)的,因为FileLock保证只能有一个进程通过lock()或者tryLock()方法获得文件锁。
3. 文件锁的效果是与操作系统相关的。一些系统中文件锁是强制性的(mandatory),就当Java的某进程获得文件锁后,操作系统将保证其它进程无法对 文件做操作了。而另一些操作系统的文件锁是询问式的(advisory),意思是说要想拥有进程互斥的效果,其它的进程也必须也按照API所规定的那样来 申请或者检测文件锁,不然,将起不到进程互斥的功能。所以,文档里建议将所有系统都当做是询问式系统来处理,这样程序更加安全也更容易移植。
更多推荐
所有评论(0)