6

我目前正在开发某种数据库基准应用程序。基本上,我要做的是使用线程模拟一定数量的客户端,这些客户端在特定时间段内都对数据库重复相同的操作(例如:读取操作)。
在此期间,我想在每个线程中测量从数据库中获取答案的平均延迟。

我的第一选择是依靠 ThreadMXBean 的 getThreadCpuTime() 方法(http://docs.oracle.com/javase/7/docs/api/java/lang/management/ThreadMXBean.html)但关键是操作完成太快无法测量(操作前的 getThreadCpuTime() 等于操作后的 getThreadCpuTime())。

我做了一个小实验来理解和说明问题:

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

我无法获得所有MyThread实例的执行时间,但实例没有问题LongRunningThread。就像我说的,我的假设是第一个线程完成的操作发生得太快而无法实际测量。有什么办法可以实现我想要做的事情吗?是否可以测量如此短时间运行的线程的执行时间?

提前感谢您的帮助:)

4

3 回答 3

3

您是否考虑过这个框架http://metrics.codahale.com/。它非常非常好,并且内置了通过 JMX 公开指标的支持

于 2013-02-02T18:25:06.597 回答
1

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. The javadocs for ThreadMXBean.getThreadCpuTime(...) say:

Returns the total CPU time for a thread of the specified ID in nanoseconds. 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.

于 2013-02-02T20:11:06.667 回答
0

作为更简单的解决方案,您可以使用下一个:

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");
    }
}

如果您不需要纳秒精度,则可以System.currentTimeMillis()改用。

于 2013-02-02T18:43:31.883 回答