简体   繁体   English

可靠的跨平台方式在Java中获取方法时间

[英]Reliable cross-platform way to obtain the method time in Java

This question is not about benchmark. 这个问题与基准无关。

I have a java thread cycle that should to operate close to a period time T: 我有一个java线程周期,应该在接近周期时间T操作:

public class MyRunnable implements Runnable {

    private final long period = 10000L; //period T, in this case 10 secs

    public void run() {
        while() {
            long startTime = this.getTime();

            this.doStuff();

            long endTime = this.getTime();
            long executionTime = endTime - startTime;
            if(executionTime < this.period) {
                long sleepTime = (this.period - executionTime);
                try {
                     Thread.sleep(sleepTime);
                } catch(InterruptedException iex) {/*handle iex*/}
            }
        }
    }

    private long getTime() {
        return System.currentTimeMillis();
    }

    private void doStuff() {/*do stuff*/}

} 

Of course, depending on the schedule premption choices, Thread.sleep(sleepTime) could be slightly greater than sleepTime . 当然,根据计划预设选择, Thread.sleep(sleepTime)可能略大于sleepTime But, in average, this approach provides a close averaged approximation to the period T. 但是,平均而言,这种方法提供了与周期T的近似平均近似值。

The problem 问题

The method: 方法:

private long getTime() {
    return System.currentTimeMillis();
}

provides the wall clock reference time. 提供挂钟参考时间。 If the machine's clock changes, forward or backwards, this implementation fails to provide a close approximation for the period T. For instance: 如果机器的时钟向前或向后变化,则此实现无法提供T期间的近似值。例如:

long t1 = getTime();
Thread.sleep(30000);
long t2 = getTime();
System.out.println(t2 - t1);

prints something like 204283 if someone manually changes the clock three minutes ahead while Thread.sleep(30000) "runs". 如果有人在Thread.sleep(30000) “运行”的情况下提前三分钟手动更改时钟,则打印类似204283的内容。

Since the system clock is always changing (timeserver synchronization, system load, user settings, etc...) using System.currentTimeMillis() is not realiable enough for my needs. 由于使用System.currentTimeMillis()的系统时钟总是在变化(时间服务器同步,系统负载,用户设置等System.currentTimeMillis()因此不能满足我的需求。

Failed solution 解决方案失败

In order to provide a more robust time reference I tried the following implementation for getTime method: 为了提供更强大的时间参考,我尝试了以下getTime方法的实现:

long getTime() {
    long result;
    ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
    if (mxBean.isThreadCpuTimeSupported()) {
        result = mxBean.getCurrentThreadCpuTime()/1000000L;
    } else {
        throw new RuntimeException("unsupported thread cpu time");
    }
    return result;
}

The problem of getCurrentThreadCpuTime is that the resulting amount of time is the CPU time consumed by the Thread, not the time left at that instant. getCurrentThreadCpuTime的问题是得到的时间量是线程消耗的CPU时间,而不是该时刻剩余的时间。 Time left when the Thread is sleeping or blocked is not taken in account. 线程处于休眠状态或被阻止时的剩余时间未考虑在内。 For example: 例如:

long t1 = getTime();
Thread.sleep(30000);
long t2 = getTime();
System.out.println(t2 - t1);

surprising prints "0" (zero) by the getCurrentThreadCpuTime getTime's implementation. 令人惊讶的是, getCurrentThreadCpuTime getTime的实现打印出“0”(零)。

What I want 我想要的是

I guess that what I need is something like this: 我想我需要的是这样的:

private long getTime() {
    long cpuCycles = getAmountOfCPUCyclesSinceTheProgramStarted();
    long cpuFrequency = getCPUFrequency();
    long result = cpuCycles / cpuFrequency;
    return result;
}

The problem is that I didn't found a java way to implement getAmountOfCPUCyclesSinceTheProgramStarted() and getCPUFrequency() in a cross platform fashion. 问题是我没有找到一种java方式以跨平台的方式实现getAmountOfCPUCyclesSinceTheProgramStarted()getCPUFrequency()

Finally, my question is: how to obtain the spent time of a method in java in a reliable and cross-platform way? 最后,我的问题是:如何以可靠和跨平台的方式获取java中方法的花费时间?

Try using System.nanoTime() , it seems to be what you are looking for. 尝试使用System.nanoTime() ,它似乎是你正在寻找的。

From the docs: 来自文档:

This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. 此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关。

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

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