为什么锁定文件时会发生 OverlappingFileLockException?

jer*_*jtu 5 java multithreading locking

我尝试锁定一个文件并使用以下代码写入它:

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();
          }
     }
 }
Run Code Online (Sandbox Code Playgroud)

并新建两个带有该类实例的线程:

    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();
Run Code Online (Sandbox Code Playgroud)

然后我收到错误 OverlappingFileLockException。我想知道为什么会发生这种情况,因为我只在每个线程中锁定文件一次?如何修复我的代码?

Att*_*ila 4

您不能同时锁定同一文件多次。您需要使用 java 锁对象来确保一次只有一个线程尝试锁定文件,或者协调线程等待,直到没有其他线程锁定。

手册中:

文件锁代表整个 Java 虚拟机。它们不适合控制同一虚拟机内的多个线程对文件的访问。