如何分析线程生命周期性能

时间:2014-06-26 07:41:07

标签: java multithreading webserver threadpool profiler

在构建HTTP Web服务器的上下文中......我们理解,从理论上讲,每个请求创建和销毁线程的成本相对较高,并且不能扩展。这是常识(或者我希望是这样)。线程池是这里的解决方案......但是我想要在较低层次上理解事物,而不是简单地接受理论为真。

当然,我们可以使用JMeter运行黑盒测试来查看应用程序在负载下的执行情况,但是如果我想实际观察为什么会发生呢?分析器工具能告诉我每个请求的线程分配的成本和确切原因是多少吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

Web服务器池线程,这意味着稍后的请求可能正在使用完全相同的线程,这可以通过Thread.currentThread()。getId()获取线程ID来观察。应该没什么可担心的,但如果您打算从servlet或过滤器创建自己的线程,请不要这样做。这可能会导致DOS攻击和服务器泛滥。您应该能够通过servlet过滤器添加监视功能,这将允许您在当前线程上提取统计信息以及执行一些基本的性能统计信息。

答案 1 :(得分:1)

如果您想自己测量一下,可以这样做。

当这种智慧被认定时很可能是很久以前创造线程的时候要贵得多。例如在Linux上,每个线程都是一个新进程。

另外"昂贵"意味着不同的应用程序。如果您的系统中的每个请求都需要很长时间,那么添加毫秒不会产生太大的影响。如果每个请求都需要几毫秒,那么为了启动线程而添加一毫秒就非常糟糕了。

import java.util.ArrayList;
import java.util.List;

public class ThreadRestarterMain {
    public static void main(String... ignored) throws InterruptedException {
        long start = System.currentTimeMillis();
        // time how long it takes to start a few threads and stop them again.
        int threads = 2000;
        List<Thread> threadList = new ArrayList<>();
        while (threadList.size() < threads) {
            Thread e = new Thread(new Runnable() {
                @Override
                public void run() {
                    Thread.yield();
                }
            });
            e.start();
            threadList.add(e);
        }
        for (Thread thread : threadList) {
            thread.join();
        }
        long time = System.currentTimeMillis() - start;
        System.out.printf("Took %.3f ms on average to start/stop a thread%n", (double) time / threads);
    }
}

这会打印类似

的内容
Took 0.055 ms on average to start/stop a thread

只有你知道这是否是一个大数字。

注意:如果您有线程本地资源,这可以使此时间更长。这又取决于你在做什么。

答案 2 :(得分:1)

前一段时间我有类似的任务。我们决定坚持使用JMeter,但也在我们的代码中添加了日志记录。我们只记录了处理我们怀疑瓶颈的代码的特定部分所花费的时间。然后我们运行JMeter来使我们的系统处于负载状态。

这样您就无法观察到所有代码,但至少可以观察到它的不同部分。

我不认为这个解决方案很漂亮,但你可能知道如何改进它。