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 及更高版本中。您可以在 JDK 路径/bin 文件夹中找到 visualVm。

VisualVM 在特定于该应用程序的选项卡中显示本地和远程应用程序的数据。应用程序选项卡显示在应用程序窗口右侧的主窗口中。您可以一次打开多个应用程序选项卡。每个应用程序选项卡都包含显示有关应用程序的不同类型信息的子选项卡。VisualVM 在“线程”选项卡中显示有关线程活动的实时高级数据。

在此处输入图像描述

于 2012-12-15T19:55:38.660 回答
1

对于第一个问题:考虑使用VisualVM来监控这些线程。或者只是使用你的 IDE 调试器(eclipse 有这样的功能 imo)。

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

InterruptedExceptions 如果Thread.interrupt()在线程休眠时被调用,则发生。然后Thread.sleep()被中断,线程将跳转到捕获代码中。
在您的示例中,您的线程休眠 4 秒。如果另一个线程Thread.interrupt()在您的睡眠线程上调用,它将执行threadMessage("I wasn't done!");.
嗯.. 正如你现在可能已经理解的那样,catch 块处理sleep()- 方法,而不是线程抛出的异常。它会引发一个已检查的异常,您必须捕获该异常。

于 2012-12-15T19:56:57.000 回答
0

如果您不能使用 VisualVM 之类的工具(这非常有用,恕我直言),您还可以将 Java 中的线程堆栈转储到您的日志文件中。当超过某些阈值时,我在我的服务器程序上使用此类转储。我发现将此类快照作为程序的一部分非常有帮助。为您提供一些关于系统崩溃之前发生的事情的提示,并且使用分析器为时已晚(死锁、OutOfMemory、减速等)。看看这里的代码:以编程方式触发完整的堆栈转储?

于 2012-12-15T20:20:00.107 回答