java 为什么在锁定文件时会发生 OverlappingFileLockException?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9906161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does OverlappingFileLockException happen when locking a file?
提问by jerry_sjtu
I try to lock a file and write to it with the code below:
我尝试锁定一个文件并使用以下代码写入它:
public class TrainSetBuildTask implements Runnable {
private String pathname;
public TrainSetBuildTask(String pathname){
this.pathname = pathname;
}
@Override
public void run() {
try {
String content = "content\n";
//write to a file
FileOutputStream os = new FileOutputStream(new File(pathname), true);
FileChannel channel = os.getChannel();
FileLock lock = channel.tryLock();
if (lock != null) {
ByteBuffer bytes = ByteBuffer.wrap(content.getBytes());
channel.write(bytes);
lock.release();
}
channel.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And new two thread with instances of the class:
和新的两个线程与类的实例:
String pathname = "/home/sjtu123/test.arff";
TrainSetBuildTask task1 = new TrainSetBuildTask(pathname);
Thread t1 = new Thread(task1);
TrainSetBuildTask task2 = new TrainSetBuildTask(pathname);
Thread t2 = new Thread(task2);
t1.start();
t2.start();
Then I get the error OverlappingFileLockException. I wonder why this happens since I just lock the file once in each thread? How can fix my code?
然后我收到错误 OverlappingFileLockException。我想知道为什么会发生这种情况,因为我只是在每个线程中锁定文件一次?如何修复我的代码?
回答by Attila
You cannot lock the same file more than once simultaneously. Either you need to use java lock objects to ensure only one thread tries to lock the file at a time, or otherwise coordinate the threads to wait until no other thread is locking.
您不能同时锁定同一个文件多次。您需要使用 java lock 对象来确保一次只有一个线程尝试锁定文件,或者以其他方式协调线程等待直到没有其他线程锁定。
From the manual:
从手册:
File locks are held on behalf of the entire Java virtual machine. They are not suitable for controlling access to a file by multiple threads within the same virtual machine.
代表整个 Java 虚拟机持有文件锁。它们不适合控制同一虚拟机内的多个线程对文件的访问。
回答by Johannes
Files are locked globally not just per-thread or per-process.
文件被全局锁定,而不仅仅是每个线程或每个进程。
You need to run your two thread sequentially like this:
您需要像这样按顺序运行两个线程:
String pathname = "/home/sjtu123/test.arff";
TrainSetBuildTask task1 = new TrainSetBuildTask(pathname);
Thread t1 = new Thread(task1);
TrainSetBuildTask task2 = new TrainSetBuildTask(pathname);
Thread t2 = new Thread(task2);
t1.start();
t1.join(); // Wait for t1 to die.
t2.start();
New version after comments:
评论后的新版本:
FileWriter pathname = new FileWriter("/home/sjtu123/test.arff");
TrainSetBuildTask task1 = new TrainSetBuildTask(pathname);
Thread t1 = new Thread(task1);
TrainSetBuildTask task2 = new TrainSetBuildTask(pathname);
Thread t2 = new Thread(task2);
t1.start();
t2.start();
t1.join();
j2.join();
synchronized (pathname){
pathname.close();
}
and
和
public class TrainSetBuildTask implements Runnable {
private FileWriter pathname;
public TrainSetBuildTask(FileWriter pathname){
this.pathname = pathname;
}
@Override
public void run() {
try {
// Do work
synchronized (pathname){
// Write to file
}
} catch (IOException e) {
e.printStackTrace();
}
}
}