7

Java で読み込むブロッキング ファイルを設定したいと思います。つまり、によってラップされFileInputStream、任意のread()メソッドが呼び出されると、呼び出しがブロックされるようなファイルを用意します。

OSに依存しない簡単な方法は考えられません.UnixのようなOSではmkfifo、そのファイルを使用してFIFOを作成して読み取ることができます。考えられる回避策は、非常に大きなファイルを作成してそこから読み取ることです.スタックをキャプチャする前に読み取りが完了する可能性は低いですが、それは醜くて遅いです.

対応するソケットのread()ケースは簡単にセットアップできます。自分でソケットを作成してそこから読み取ると、確定的なブロッキングを行うことができます。

その目的は、メソッドのスタックを調べて、そのような場合にトップ フレームが何であるかを判断することです。実行中のすべてのスレッドのスタック トレースを定期的にサンプリングし、そのスレッドが現在行っていることを分類しようとするコンポーネントがあるとします。実行できることの 1 つは、ファイル IO です。そのため、ファイル IO 中に「スタックのトップ」がどのように見えるかを知る必要があります。私はすでに実験(さまざまな方法でファイルを読み取り、スタックをサンプリングするだけ)によってそれを決定しましたが、これが変更された場合に失敗するテストを書きたいと思っています。

このようなテストを作成する自然な方法は、ファイルの読み取りを行うスレッドを開始してから、トップ フレームを調べることです。これを確実に行うには、ブロッキング読み取りが必要です (そうしないと、スタック トレースが取得される前にスレッドが読み取りを終了する可能性があります)。

4

6 に答える 6

1

FileInputStream.read()私の理解では、メソッドのスタック トレースを検査するテストを書きたいと考えています。メソッドFileInputStreamをオーバーライドした場合の子孫はどうなりますか?read()

子孫を検査する必要がない場合は、JVM ツール インターフェイスを使用して、実行時に目的のメソッドにブレーク ポイントを挿入し、このイベントのイベント処理 (ブレーク ポイント) でスタック トレースをダンプできると思います。ダンプが完了したら、ブレーク ポイントを削除して実行を続行します。(これはすべて、このAPIを使用して実行時に発生します。黒魔術はありません:))

于 2015-01-29T17:58:30.883 に答える
1

とにかく、読み取り時に常にブロックされる OS に依存しない方法でファイルを作成する方法を知りません。

特定の関数が呼び出されたときにスタック トレースを見つけようとしている場合は、デバッガーでプログラムを実行し、その関数にブレーク ポイントを設定します。ただし、メソッド ブレークポイントはプログラムの速度を低下させ、タイミングが重要な場合に通常得られる結果とは異なる結果をもたらします。

プログラムのソース コードにアクセスできる場合は、実際のファイルを拡張するが読み取り時に常にブロックする偽の FileInputStream を作成できます。必要なのは、コード全体で import ステートメントを切り替えることだけです。ただし、これは import ステートメントを切り替えることができない場所をキャプチャできず、コードが多い場合は面倒になる可能性があります。

プログラムのソース コードを変更したりコンパイルしたりせずに独自の FileInputStream を使用する場合は、実際のクラスの代わりにカスタムの FileInputStream クラスをロードするカスタム クラス ローダーを作成できます。コマンドラインで使用するクラスローダーを指定するには、次のようにします。

java -Djava.system.class.loader=com.test.MyClassLoader xxx

考えてみると、read() でブロックするカスタム FileInputStream を作成する代わりに、read() でスタック トレースを出力するカスタム FileInputStream を作成するという、さらに良いアイデアがあります。その後、カスタム クラスは実際のバージョンの read() を呼び出すことができます。このようにして、すべての呼び出しのすべてのスタック トレースを取得します。

于 2015-01-20T23:48:50.573 に答える
0

ファイルのアクセス時間の変更を別のスレッドで監視し、それが発生したときに jvm スレッド ダンプを生成することができます。コードでのスレッド ダンプの生成に関しては、試したことはありませんが、ここで回答されているようです:再起動せずに Java スレッド ダンプを生成します。

これがスレッド間のタイミングでどれだけうまく機能するかはわかりませんが、これはかなり近づくはずだと思います. また、このソリューションをテストしていないため、このソリューションの OS 独立性について 100% ではありませんが、最新のシステムのほとんどで動作するはずです。java.nio.file.attribute.BasicFileAttributes の javadoc を参照して、サポートされていない場合に何が返されるかを確認してください。

于 2015-01-27T20:23:32.093 に答える
0

Reader1 つの秘訣は、API を の代わりにを返すように変更できる場合File、文字列をカスタムStringReader(など) でラップして、実際の作業を行う前にさまざまなメソッドをclass SlowAsRubyStringReader extends Readerでオーバーライドできることです。もちろん、テスト中だけです。 int read()Thread.sleep(500)

@参照http://docs.oracle.com/javase/7/docs/api/java/io/StringReader.html

ここには、 Files だけでなく、より大きな問題があると思います。テスト ケース中に API が呼び出されるコンテキストを調べたいと思いませんか? つまり、スタックを調べて、「あはは! JustTookABath オブジェクトから MudFactory API を呼び出しているのを見つけました。とんでもない!」と言うことができます。この場合、動的プロキシを掘り下げる必要があるかもしれません。これにより、関数呼び出しをハイジャックしたり、アスペクト指向プログラミングを使用したりできます。これにより、同じことをより体系的な方法で行うことができます。http://en.wikipedia.org/wiki/Pointcutを参照

于 2015-02-01T12:40:03.960 に答える