3

タイトルはそれをすべて言います。以下に含まれるコードがいくつかありますが、スレッドに関連する統計/情報 (つまり、実行されている異なるスレッドの数、異なるスレッドの名前) を取得する方法を考えています。22 33 44 55一貫性を保つために、コマンド ライン引数として使用してコードが実行されるイメージを示します。

また、この特定の例では、try ブロックの目的が何なのか疑問に思っています。try ブロックが一般的に何をするかは理解していますが、具体的には try ブロックがスレッドに対して何をするかを理解しています。

public class SimpleThreads {
//Display a message, preceded by the name of the current thread
static void threadMessage(String message) {
long threadName = Thread.currentThread().getId();
System.out.format("id is %d: %s%n", threadName, message);
}
private static class MessageLoop implements Runnable {
    String info[];
    MessageLoop(String x[]) {
        info = x;
    }
    public void run() {
        try {
            for (int i = 1; i < info.length; i++) {
                //Pause for 4 seconds
                Thread.sleep(4000);
                //Print a message
                threadMessage(info[i]);
            }
        } catch (InterruptedException e) {
            threadMessage("I wasn't done!");
        }
    }
}

public static void main(String args[])throws InterruptedException {
    //Delay, in milliseconds before we interrupt MessageLoop
    //thread (default one minute).
    long extent = 1000 * 60;//one minute
    String[] nargs =  {"33","ONE", "TWO"};
    if (args.length != 0) nargs = args;
    else System.out.println("assumed: java SimpleThreads 33 ONE TWO");
    try {
        extent = Long.parseLong(nargs[0]) * 1000;
    } catch (NumberFormatException e) {
        System.err.println("First Argument must be an integer.");
        System.exit(1);
    }
    threadMessage("Starting MessageLoop thread");
    long startTime = System.currentTimeMillis();
    Thread t = new Thread(new MessageLoop(nargs));
    t.start();

    threadMessage("Waiting for MessageLoop thread to finish");
    //loop until MessageLoop thread exits
    int seconds = 0;
    while (t.isAlive()) {
        threadMessage("Seconds:  " + seconds++);
        //Wait maximum of 1 second for MessageLoop thread to
        //finish.
        t.join(1000);
        if (((System.currentTimeMillis() - startTime) > extent) &&
                t.isAlive()) {
            threadMessage("Tired of waiting!");
            t.interrupt();
            //Shouldn't be long now -- wait indefinitely
            t.join();
        }

    }
    threadMessage("All done!");
    }
}
4

3 に答える 3

3

スレッドの監視にVisualVMを使用できます。これは、JDK 6 update 7 以降に含まれています。VisualVm は JDK パス/bin フォルダーにあります。

VisualVM は、ローカルおよびリモート アプリケーションのデータを、そのアプリケーションに固有のタブに表示します。アプリケーション タブは、アプリケーション ウィンドウの右側のメイン ウィンドウに表示されます。一度に複数のアプリケーション タブを開くことができます。各アプリケーション タブには、アプリケーションに関するさまざまな種類の情報を表示するサブタブが含まれています。VisualVM は、[スレッド] タブにスレッド アクティビティに関するリアルタイムの高レベル データを表示します。

ここに画像の説明を入力

于 2012-12-15T19:55:38.660 に答える
1

最初の問題: VisualVMを使用してこれらのスレッドを監視することを検討してください。または、IDEデバッガーを使用するだけです(Eclipseにはそのような機能があります)。

I am also wondering what the purpose of the try blocks are in this particular example.

InterruptedExceptionThread.interrupt()スレッドがスリープしている間に が呼び出された場合に発生します。次に、Thread.sleep()が中断され、スレッドがキャッチコードにジャンプします。
あなたの例では、スレッドは 4 秒間スリープします。Thread.interrupt()スリープ中のスレッドで別のスレッドが呼び出されると、そのスレッドが実行されthreadMessage("I wasn't done!");ます。
さて、お分かりかもしれませんが、catch ブロックsleep()はスレッドによってスローされた例外ではなく、メソッドを処理します。強制的にキャッチするチェック例外をスローします。

于 2012-12-15T19:56:57.000 に答える
0

VisualVM(非常に便利なIMHO)のようなツールを使用できない場合は、Javaのスレッドスタックをログファイルなどにダンプすることもできます。特定のしきい値を超えたときに、サーバープログラムでこのようなダンプを使用しています。プログラムの一部としてこのようなスナップショットを作成することは非常に役に立ちました。システムがクラッシュし、プロファイラー(デッドロック、OutOfMemory、スローダウンなど)を使用するには遅すぎる前に何が起こったかについてのヒントを提供します。ここでコードを見てください:プログラムで完全なスタックダンプをトリガーしますか?

于 2012-12-15T20:20:00.107 に答える