Javaでファイルをロックしているスレッドを見つける方法は?
-
24-09-2019 - |
質問
プログラム内の別のスレッドが以前に使用したファイルを削除しようとしています。
ファイルを削除することはできませんが、どのスレッドがファイルを使用しているかを把握する方法がわかりません。
では、どのスレッドがJavaでファイルをロックしているかを知るにはどうすればよいですか?
解決
私はまっすぐな答えを持っていません(そして、私も1つないと思います。これはJVMレベルではなくOSレベル(ネイティブ)で制御されています)、私も答えの価値を見ていません(どのスレッドであるかを見つけたら、プログラムでファイルを閉じることはできませんが、ファイルがまだ開いているときに削除できないことが通常発生することはまだわかりません。これはあなたがそうするときに起こるかもしれません いいえ 明示的に呼び出します Closeable#close()
に InputStream
, OutputStream
, Reader
また 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のスタッフ全体を通して、コードが適切であることを確認してください 閉鎖 使用後のリソース。 通常のイディオム これを行うことです try-with-resources
声明, 、そのため、とにかくリソースが解放されることを確実にすることができます IOException
. 。例えば
try (OutputStream output = new FileOutputStream(file)) {
// ...
}
それをしてください どれか InputStream
, OutputStream
, Reader
と Writer
, 、などを実装するものは何でも 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) {}
}
これがあなたの特定の問題の根本原因を特定するのに役立つことを願っています。
他のヒント
この質問について、私はこの答えを見つけようとし、尋ねます この質問 答えを見つける:
JVMスレッドロックa ファイル 排他的には、JVMロックもいくつかあります Javeオブジェクト, 、たとえば、私は私の場合に見つけます:
- sun.nio.fs.nativebuffer
- sun.nio.ch.util $ buffercache
したがって、このロックされたJavaオブジェクトを見つけて分析するだけで、ファイルがロックされたスレッドが見つかります。
ファイルがただ開いている場合(ロックされていない場合)、ファイルがスレッドだけでロックされている場合は機能していると確信しています(java.nio.channels.filelock、java.nio.channels.filechannelなどを使用してくださいの上)
詳細については、参照してください この質問