如何在Java中获取线程信息/统计信息

时间:2012-12-15 19:49:13

标签: java multithreading

标题说明了一切。我有一些代码包含在下面,我想知道如何获取与线程相关的统计信息/信息(即运行多少个不同的线程,不同线程的名称)。为了保持一致,使用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!");
    }
}

3 个答案:

答案 0 :(得分:3)

您可以使用VisualVM进行线程监控。它包含在JDK 6 update 7及更高版本中。您可以在JDK path / bin文件夹中找到visualVm。

  

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

enter image description here

答案 1 :(得分:1)

第一期: 考虑使用VisualVM来监控这些线程。或者只使用你的IDE调试器(eclipse有这样的函数imo)。

I am also wondering what the purpose of the try blocks are in this particular example.
如果在线程正在休眠时调用InterruptedException,则会出现

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

答案 2 :(得分:0)

如果你不能使用像VisualVM这样的工具(非常有用,恕我直言),你也可以用Java转储线程堆栈,例如:到您的日志文件。我在服务器程序上使用这样的转储,当超过某些阈值时。我发现做这样的快照作为程序的一部分非常有帮助。给你一些关于系统崩溃之前发生的事情的提示,使用分析器为时已晚(死锁,OutOfMemory,减速等)。在这里查看代码:Trigger complete stack dump programmatically?