【发布时间】:2010-02-01 15:03:22
【问题描述】:
我正在尝试删除我程序中的另一个线程之前使用过的文件。
我无法删除该文件,但我不确定如何确定哪个线程可能正在使用该文件。
那么在java中如何找出是哪个线程锁定了文件呢?
【问题讨论】:
-
文件被进程锁定,而不是线程。如前所述,您必须先关闭文件,然后才能将其删除。我建议您首先查看文件的打开位置。
标签: java multithreading file-locking
我正在尝试删除我程序中的另一个线程之前使用过的文件。
我无法删除该文件,但我不确定如何确定哪个线程可能正在使用该文件。
那么在java中如何找出是哪个线程锁定了文件呢?
【问题讨论】:
标签: java multithreading file-locking
我没有一个直接的答案(我也不认为有一个,这是在操作系统级别(本机)控制的,而不是在 JVM 级别),我也没有真正看到答案(一旦发现它是哪个线程,您仍然无法以编程方式关闭文件),但我认为您还不知道无法删除通常是在文件仍处于打开状态时引起的。当您不在InputStream、OutputStream、Reader 或Writer 上显式调用Closeable#close() 时可能会发生这种情况,这些Writer 是围绕相关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 的情况下也是如此。例如
try (OutputStream output = new FileOutputStream(file)) {
// ...
}
为任何做到这一点(使用new 关键字)。
这在某些实现(例如ByteArrayOutputStream)上在技术上是不需要的,但为了清楚起见,只要在任何地方都遵循 close-in-finally 习惯用法,以避免误解和重构错误。
如果您还没有使用 Java 7 或更高版本,请改用下面的 try-finally 成语。
OutputStream output = null;
try {
output = new FileOutputStream(file);
// ...
} finally {
if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
}
希望这有助于确定您的特定问题的根本原因。
【讨论】:
关于这个问题,我也试着找出这个答案,并询问this question并找到答案:
每当JVM线程独占锁定一个文件时,JVM也会锁定 例如,我发现一些 Jave 对象:
- sun.nio.fs.NativeBuffer
- sun.nio.ch.Util$BufferCache
所以你只需要找到这个锁定的 Java 对象并分析它们并 你发现哪个线程锁定了你的文件。
如果文件只是打开(没有专门锁定),我不确定它是否有效,但我确信如果文件被 Thread 专门锁定(使用 java.nio.channels.FileLock、java.nio.channels.文件通道等)
更多信息见this question
【讨论】: