简体   繁体   English

衡量Java短时间运行线程的执行时间

[英]Measure java short time running thread execution time

I'm currently working on some sort of database benchmark application. 我目前正在开发某种数据库基准测试应用程序。 Basically, what I'm trying to do is to simulate using threads a certain number of clients that all repeat the same operation (example: a read operation) against the database during a certain period of time. 基本上,我想做的是使用线程模拟一定数量的客户端,这些客户端在特定时间段内都对数据库重复相同的操作(例如:读取操作)。
During this time, I want, in each thread, to measure the average delay for getting an answer from the database. 在这段时间内,我希望在每个线程中测量从数据库获取答案的平均延迟。

My first choice was to rely on ThreadMXBean's getThreadCpuTime() method ( http://docs.oracle.com/javase/7/docs/api/java/lang/management/ThreadMXBean.html ) but the point is that the operation is done too quickly to be measured (getThreadCpuTime() before the operation is equal to getThreadCpuTime() after the operation). 我的第一选择是依靠ThreadMXBean的getThreadCpuTime()方法( http://docs.oracle.com/javase/7/docs/api/java/lang/management/ThreadMXBean.html ),但要点是操作已完成太快而无法测量(操作之前的getThreadCpuTime()等于操作之后的getThreadCpuTime())。

I made a little experiment to understand and illustrate the problem: 我做了一些实验来理解和说明问题:

public class ExampleClass {
class LongRunningThread extends Thread {
    private int n;
    public LongRunningThread(int n) {
        this.n = n;
    }
    public void run() {
        ArrayList l = new ArrayList();
        for (int i = 0; i < n; i++) {
            l.add(new Object());
        }
        long time = ManagementFactory.getThreadMXBean().getThreadCpuTime(this.getId());
        System.out.println("Long running thread " + this.getId() + " execution time: " + time);
    }
}

class MyThread extends Thread {
    int n;
    public MyThread(int n) {
        this.n = n;
    }
    public void run() {
        ArrayList l = new ArrayList();
        for (int i = 0; i < n; i++) {
            l.add(new Object());
        }
        long time = ManagementFactory.getThreadMXBean().getThreadCpuTime(this.getId());
        System.out.println("My thread " + this.getId() + " execution time: " + time);
    }
}

public static void main(String [] args) {
        System.out.println("Cpu time supported? " + ManagementFactory.getThreadMXBean().isThreadCpuTimeSupported());
    System.out.println("Cpu time enabled? " + ManagementFactory.getThreadMXBean().isThreadCpuTimeEnabled());
    for (int i = 1; i < 10; ++i) {
        new LongRunningThread(i*1000000).start();
    }

    for (int i = 1; i < 10; ++i) {
        new MyThread(i*100).start();
    }
}


Output:
Cpu time supported? true
Cpu time enabled? true
My thread 18 execution time: 0
My thread 26 execution time: 0
My thread 20 execution time: 0
My thread 22 execution time: 0
My thread 24 execution time: 0
My thread 21 execution time: 0
My thread 25 execution time: 0
My thread 19 execution time: 0
My thread 23 execution time: 0
Long running thread 9 execution time: 15600100
Long running thread 10 execution time: 15600100
Long running thread 11 execution time: 46800300
Long running thread 12 execution time: 31200200
Long running thread 14 execution time: 78000500
Long running thread 13 execution time: 78000500
Long running thread 17 execution time: 124800800
Long running thread 15 execution time: 140400900
Long running thread 16 execution time: 109200700

I cannot get the execution time for all MyThread instances but no problem for LongRunningThread instances. 我无法获取所有MyThread实例的执行时间,但对于LongRunningThread实例来说却没有问题。 Like I said, my hypothesis is that the operation done by the first threads happen too fast to be actually measured. 就像我说的那样,我的假设是,第一个线程完成的操作发生得太快而无法实际测量。 Is there any way to achieve what I'm trying to do? 有什么方法可以实现我的目标? Is it possible to measure the execution time for such short time running threads? 可以测量这么短时间运行的线程的执行时间吗?

Thanks in advance for you help :) 在此先感谢您的帮助:)

Have you considerd this framework http://metrics.codahale.com/ . 您是否考虑过此框架http://metrics.codahale.com/ It's very very good and comes with built in support for exposing metrics via JMX 它非常好,并且内置支持通过JMX公开指标

Is it possible to measure the execution time for such short time running threads? 可以测量这么短时间运行的线程的执行时间吗?

Without measuring wall-clock times with the nano-second clock, the answer may be no. 如果不使用纳秒时钟来测量挂钟时间,答案可能是否定的。 For small loops, the measured CPU time may be smaller than the precision of the method. 对于小循环,测得的CPU时间可能小于该方法的精度。 The javadocs for ThreadMXBean.getThreadCpuTime(...) say: ThreadMXBean.getThreadCpuTime(...)说:

Returns the total CPU time for a thread of the specified ID in nanoseconds. 返回指定ID的线程的总CPU时间(以纳秒为单位)。 The returned value is of nanoseconds precision but not necessarily nanoseconds accuracy. 返回的值具有纳秒精度,但不一定是纳秒精度。

One thing to consider would be to take the CPU time if it is > 0 and take the wall-clock time if it is == 0. 要考虑的一件事是,如果CPU时间> 0,则将其占用时间;如果== 0,则将采用壁钟时间。

as easier solution you can use next : 作为更简单的解决方案,您可以使用next:

class MyThread extends Thread {
    int n;
    public MyThread(int n) {
        this.n = n;
    }
    public void run() {
        long startTime = System.nanoTime();
        ArrayList l = new ArrayList(n);
        for (int i = 0; i < n; i++) {
            l.add(new Object());
        }
        long time = System.nanoTime() - startTime;
        System.out.println("My thread " + this.getId() + " execution time: " + time + " ns");
    }
}

if you don't need nanoseconds precision you can use System.currentTimeMillis() instead. 如果不需要纳秒精度,则可以使用System.currentTimeMillis()代替。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM