如何找出哪个线程在java中锁定文件?

时间:2010-02-01 15:03:23

标签: java multithreading file-locking

我正在尝试删除程序中其他线程以前使用过的文件。

我无法删除该文件,但我不知道如何确定哪个线程可能正在使用该文件。

那么如何找出哪个线程在java中锁定文件?

2 个答案:

答案 0 :(得分:7)

我没有一个直接的答案(我不认为也有一个,这是在操作系统级别(本机)控制,而不是在JVM级别)我也没有真正看到它的价值答案(一旦你发现它是哪个线程,你仍然无法以编程方式关闭文件),但我认为你还不知道当文件仍处于打开状态时通常无法删除。如果您在InputStreamOutputStreamReaderWriter周围构建明确调用Closeable#close(),则可能会发生这种情况问题File

基本演示:

public static void main(String[] args) throws Exception {
    File file = new File("c:/test.txt"); // Precreate this test file first.
    FileOutputStream output = new FileOutputStream(file); // This opens the file!
    System.out.println(file.delete()); // false
    output.close(); // This explicitly closes the file!
    System.out.println(file.delete()); // true
}

换句话说,确保在整个Java IO内容中代码在使用后正确关闭资源。 The normal idiom是在the try-with-resources statement中执行此操作,以便您可以确定资源将被释放,即使在IOException的情况下也是如此。 E.g。

try (OutputStream output = new FileOutputStream(file)) {
    // ...
}

任何 InputStreamOutputStreamReaderWriter等执行此操作AutoCloseable重新打开您自己(使用new关键字)。

技术上不需要在某些实现上,例如ByteArrayOutputStream,但是为了清楚起见,只需遵循最终的近似成语,以避免误解和重构错误。

如果您还没有使用Java 7或更新版本,请改用以下try-finally惯用法。

OutputStream output = null;
try {
    output = new FileOutputStream(file);
    // ...
} finally {
    if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
}

希望这有助于确定您特定问题的根本原因。

答案 1 :(得分:2)

关于这个问题,我也试着找出这个答案,然后问this question并找到答案:

  

每当JVM线程独占锁定文件时,JVM锁也会被锁定       一些 Jave对象,例如,我发现在我的情况下:

     
      
  • sun.nio.fs.NativeBuffer
  •   
  • sun.nio.ch.Util $ BufferCache
  •   
     

所以你需要找到这个锁定的Java对象并对它们进行分析   你找到了什么线程锁定你的文件。

如果文件只是打开(没有专门锁定),我不确定它是否有效,但我确信如果文件被Thread专门锁定(使用java.nio.channels.FileLock,java.nio。 channels.FileChannel等)

更多信息,请参阅this question