最近用到FileLock知識點,對其中的幾點做了一些實驗發現:
1.這是一個進程之間的鎖,對於同一個進程不同的線程你是不能夠同時去競爭一把鎖的。如下實驗:
package springtest.trigger;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.Channel;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Calendar;
import java.util.TimeZone;
public class Demo {
public static int i = 0 ;
private subthread sb = new subthread();
public void init()
{
<span style="color:#ff0000;"> sb.start();
new subthread().start();
</span> }
public static void main(String args[]){
while(true)
{
Demo demo = new Demo();
demo.init();
//這裏是爲了不要讓這個主線程死掉
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class subthread extends Thread{
private RandomAccessFile ra = null ;
private FileChannel channel = null ;
private FileLock fileLock = null ;
public void run()
{
while(true)
{
System.out.println(" doing ");
File file = new File("process.lck");
try {
ra = new RandomAccessFile(file, "rw");
channel = ra.getChannel();
System.out.println("there are going to get lock...");
fileLock = channel.lock(); //這裏面得到鎖了,且是在線程中得到鎖
System.out.println("geted the lock!");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//下面我想要這個地方拋出一個沒有抓住的異常
String str=null;
str.charAt(0);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fileLock != null )
{
try {
fileLock.release();
fileLock = null ;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(channel != null)
{
try {
channel.close();
channel = null ;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
}
這上面會報異常的:
doing
doing
Exception in thread "Thread-0" java.nio.channels.OverlappingFileLockException
at sun.nio.ch.FileChannelImpl$SharedFileLockTable.checkList(FileChannelImpl.java:1166)
at sun.nio.ch.FileChannelImpl$SharedFileLockTable.add(FileChannelImpl.java:1068)
at sun.nio.ch.FileChannelImpl.lock(FileChannelImpl.java:824)
at java.nio.channels.FileChannel.lock(FileChannel.java:860)
at springtest.trigger.Demo$subthread.run(Demo.java:89)
there are going to get lock...
geted the lock!
2.多進程間,是可以安然的鎖上的。當然如果你在一個進程中的線程中沒有釋放鎖,而此時這個線程由於異常而退出,但是進程沒有退出,那麼你就會發現這個鎖會一直被拿着,而沒有釋放。所以一定要將鎖釋放寫在finally裏面。